Closed dermeister0 closed 6 years ago
It is possible, I have prepared example. Will show soon.
There is new version: https://www.nuget.org/packages/Saritasa.Tools.Messages/0.5.3 . Here is a sample middleware:
/// <summary>
/// Command handler executor with transient errors handling.
/// </summary>
public class TransientErrorHandlingCommandHandlerExecutorMiddleware :
Saritasa.Tools.Messages.Commands.PipelineMiddlewares.CommandHandlerExecutorMiddleware
{
private static readonly Type[] transientExceptions = new Type[] { typeof(Exception) };
private static readonly Saritasa.Tools.Common.Utils.FlowUtils.RetryStrategy retryStrategy =
Saritasa.Tools.Common.Utils.FlowUtils.CreateIncrementDelayRetryStrategy(
delay: TimeSpan.FromSeconds(3),
increment: TimeSpan.FromSeconds(3)
);
/// <inheritdoc />
public override void Handle(IMessageContext messageContext)
{
Saritasa.Tools.Common.Utils.FlowUtils.Retry(
() =>
{
base.Handle(messageContext);
PostHandle(messageContext);
},
retryStrategy,
transientExceptions);
}
/// <inheritdoc />
public override Task HandleAsync(IMessageContext messageContext, CancellationToken cancellationToken)
{
return Saritasa.Tools.Common.Utils.FlowUtils.RetryAsync(
async () =>
{
await base.HandleAsync(messageContext, cancellationToken);
PostHandle(messageContext);
},
retryStrategy,
cancellationToken,
transientExceptions);
}
}
Initialization:
var pipelineContainer = new Messages.Common.DefaultMessagePipelineContainer();
var commandPipeline = pipelineContainer
.AddCommandPipeline()
.AddStandardMiddlewares(options =>
{
options.SetAssemblies(System.Reflection.Assembly.GetAssembly(typeof(Program)));
})
.Get();
commandPipeline.ReplaceMiddlewareById("CommandHandlerExecutorMiddleware", new Internal.TransientErrorHandlingCommandHandlerExecutorMiddleware()
{
CaptureExceptionDispatchInfo = true
});
var pipelineService = new Messages.Common.DefaultMessagePipelineService(null, pipelineContainer);
Usage:
public class CommandWithException
{
public int CallCount { get; set; }
public void Handle(CommandWithException command)
{
CallCount++;
if (CallCount < 2)
{
throw new InvalidOperationException();
}
}
}
var obj = new Internal.CommandWithException();
try
{
pipelineService.HandleCommand(obj);
}
catch (Exception ex)
{
}
Console.WriteLine(obj.CallCount); // 3
For example: