I have created a policy which will wait and retry for: My step is depending on output of a SELECT query. Sometimes database takes a long time around 35-45 seconds to generate the value in a table. So, I have to wait till that time to check if value populated in database table or not using Polly retry.
Below is my logic for it:
var parameters = new { PackageID = packageId };
var query = $"Select ID From Staging..Log Where StagePkg=@PackageID";
var _retryPolicy = Policy
.Handle<Exception>()
.WaitAndRetryAsync(5, retryAttempt => {
var timeToWait = TimeSpan.FromSeconds(Math.Pow(10, retryAttempt));
Console.WriteLine($"Waiting {timeToWait.TotalSeconds} seconds");
return timeToWait;
}
);
return await _retryPolicy.ExecuteAsync<BatchMailLog>(async () => await SybaseConnection.WithConnectionAsync(c => c.QueryFirstOrDefaultAsync<StageLog>(query, parameters)));
It's not getting executed the way I was thinking like: execute the query, check if query returning a value. If returned value is 0 or null then retry the query after 15 seconds and repeat till we get the value from select query.
I am getting error below:
System.NullReferenceException : Object reference not set to an instance of an object.
This error is happening because it didn't get the value from a query so it has to wait for few seconds and retry.
CodePudding user response:
The declared policy catch exception to retry the action, but the action don't throw exception, it just return null.
You can use HandleResult
to retry on a specific value like null
:
var _retryPolicy = Policy
.HandleResult<BatchMailLog>(b => b != null)
...
If you want also retry on exception :
var _retryPolicy = Policy
.Handle<Exception>()
.OrResult<BatchMailLog>(b => b != null)
...
CodePudding user response:
if returned value is 0 or null then retry the query after 15 seconds and repeat till we get the value from select query
This means you need to setup your policy in the following way:
- Trigger: if returned value is 0 or null
- Sleep duration: retry the query after 15 seconds
- Times: till we get the value from select query
With Polly you can describe this desired behaviour in the following way:
var retry = Policy
.HandleResult<BatchMailLog>(b => (b?.XYZ ?? 0) == 0) //Trigger
.WaitAndRetryForeverAsync( //Times
_ => TimeSpan.FromSeconds(15)); //Sleep duration