Skip to content

Commit

Permalink
Merge pull request #37 from hudl/ExceptionWhitelist
Browse files Browse the repository at this point in the history
Ability to ignore exception types when counting breaker errors
  • Loading branch information
robhruska committed May 23, 2015
2 parents a4a4c27 + 8ed2243 commit 32de88c
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 4 deletions.
12 changes: 10 additions & 2 deletions Hudl.Mjolnir/Command/Command.cs
Original file line number Diff line number Diff line change
Expand Up @@ -380,9 +380,17 @@ private async Task<TResult> ExecuteWithBreaker(CancellationToken cancellationTok
CircuitBreaker.MarkSuccess(stopwatch.ElapsedMilliseconds);
CircuitBreaker.Metrics.MarkCommandSuccess();
}
catch (Exception)
catch (Exception e)
{
CircuitBreaker.Metrics.MarkCommandFailure();
if (CommandContext.IsExceptionIgnored(e.GetType()))
{
CircuitBreaker.Metrics.MarkCommandSuccess();
}
else
{
CircuitBreaker.Metrics.MarkCommandFailure();
}

throw;
}

Expand Down
31 changes: 31 additions & 0 deletions Hudl.Mjolnir/Command/CommandContext.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using Hudl.Config;
using Hudl.Mjolnir.Breaker;
using Hudl.Mjolnir.External;
Expand Down Expand Up @@ -59,6 +60,10 @@ public sealed class CommandContext
private readonly ConcurrentDictionary<GroupKey, Lazy<IIsolationThreadPool>> _pools = new ConcurrentDictionary<GroupKey, Lazy<IIsolationThreadPool>>();
private readonly ConcurrentDictionary<GroupKey, Lazy<IIsolationSemaphore>> _fallbackSemaphores = new ConcurrentDictionary<GroupKey, Lazy<IIsolationSemaphore>>();

// This is a Dictionary only because there's no great concurrent Set type available. Just
// use the keys if checking for a type.
private readonly ConcurrentDictionary<Type, bool> _ignoredExceptionTypes = new ConcurrentDictionary<Type, bool>();

private IStats _stats = new IgnoringStats();

private CommandContext() {}
Expand All @@ -84,6 +89,32 @@ public static IStats Stats
}
}

/// <summary>
/// Ignored exception types won't count toward breakers tripping or other error counters.
/// Useful for things like validation, where the system isn't having any problems and the
/// caller needs to validate before invoking. This list is most applicable when using
/// [Command] attributes, since extending Command offers the ability to catch these types
/// specifically within Execute() - though there may still be some benefit in extended
/// Commands for validation-like situations where throwing is still desired.
/// </summary>
public static void IgnoreExceptions(HashSet<Type> types)
{
if (types == null || types.Count == 0)
{
return;
}

foreach (var type in types)
{
Instance._ignoredExceptionTypes.TryAdd(type, true);
}
}

internal static bool IsExceptionIgnored(Type type)
{
return Instance._ignoredExceptionTypes.ContainsKey(type);
}

internal static ICircuitBreaker GetCircuitBreaker(GroupKey key)
{
if (key == null)
Expand Down
4 changes: 2 additions & 2 deletions Hudl.Mjolnir/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@
[assembly: Guid("97b23684-6c4a-4749-b307-5867cbce2dff")]

// Used for NuGet packaging, uses semantic versioning: major.minor.patch-prerelease.
[assembly: AssemblyInformationalVersion("2.2.0")]
[assembly: AssemblyInformationalVersion("2.3.0")]

// Keep this the same as AssemblyInformationalVersion.
[assembly: AssemblyFileVersion("2.2.0")]
[assembly: AssemblyFileVersion("2.3.0")]

// ONLY change this when the major version changes; never with minor/patch/build versions.
// It'll almost always be the major version followed by three zeroes (e.g. 1.0.0.0).
Expand Down

0 comments on commit 32de88c

Please sign in to comment.