Reputation: 86987
I'm trying to test out some Polly "retry" code I have in a basic .NET Core application. I have to implement an async method (via the inherited Interface):
public Task AddMessageAsync( ... ) { .. }
Notice how the method above is NOT decorated with the async
keyword? I did that on purpose.
When I try and connect to the 3rd party service (a RabbitMQ server) where I've made hostname of this service, incorrect/typo'd, my sync code tries and fails and throws an exception. Great! but after that, the code just hangs? I thought that the code should just keep retrying.
private static Policy CheckRabbitMQPolicy(ILogger logger)
{
return Policy
.Handle<Exception>()
.WaitAndRetry(15, _ => TimeSpan.FromSeconds(2), (exception, timeSpan, __) => logger.LogWarning(...));
}
public Task AddMessageAsync(string content,
TimeSpan? timeToLive,
TimeSpan? initialVisibilityDelay,
CancellationToken cancellationToken)
{
CheckRabbitMQPolicy(_logger).Execute(() =>
{
using (var connection = _factory.CreateConnection())
{
.... // snipped //
}
});
return Task.CompletedTask;
}
So I thought that I could just return a Task.CompletedTask;
because there is no code called in this method that is async/await
. But when the exception is thrown, it's handled (the log.Warning(..)
is called / breaked-on if there's a breakpoint there), but then hangs.
How can I debug what's going on here?
As per @jeremy-thompson 's reply below, I thought I might try changing the code to:
var policyResult = CheckRabbitMQPolicy(_logger).ExecuteAndCapture(() =>
{
using (var connection = _factory.CreateConnection())
{
.... // snipped //
}
});
return policyResult.Outcome == OutcomeType.Successful
? Task.CompletedTask
: Task.FromException(policyResult.FinalException);
So this then:
Task.FromException
...This is a little bit closer, but still doesn't keep retrying 14 more times.
Upvotes: 4
Views: 1498
Reputation: 902
You should always try to present a minimum working example in the question that demonstrates the problem you're facing. I took your code and tried to make it a running example but everything seems to work as expected. It reties 14 times and it doesn't hang as you describe.
Perhaps by simplifying your code in a similar way you can figure out what's wrong in your case. Good luck!
class Program
{
static void Main()
{
var msg = new MyMessageClass();
msg.AddMessageAsync("content", TimeSpan.MaxValue, TimeSpan.MaxValue, new CancellationToken());
}
}
class MyMessageClass
{
readonly ILogger _logger = NLog.LogManager.GetCurrentClassLogger();
private static Policy CheckRabbitMQPolicy(ILogger logger)
{
return Policy
.Handle<Exception>()
.WaitAndRetry(14, _ => TimeSpan.FromSeconds(2),
(exception, timeSpan, __) =>
{
logger.Warn(exception.Message);
});
}
public Task AddMessageAsync(string content,
TimeSpan? timeToLive,
TimeSpan? initialVisibilityDelay,
CancellationToken cancellationToken)
{
var policyResult = CheckRabbitMQPolicy(_logger).ExecuteAndCapture(() => throw new Exception("Connection error"));
return policyResult.Outcome == OutcomeType.Successful
? Task.CompletedTask
: Task.FromException(policyResult.FinalException);
}
}
Upvotes: 2