I am working on a automaticretry attribute. The current github code provides a nice example. But, I would like to move the job to the end of the queue. So the job isn’t retired at once, but is the last to be tried again.
Here is my ScheduleAgainLater:
private void ScheduleAgainLater(ElectStateContext context, int retryAttempt, FailedState failedState)
{
context.SetJobParameter("RetryCount", retryAttempt);
const int maxMessageLength = 50;
var exceptionMessage = failedState.Exception.Message.Length > maxMessageLength
? failedState.Exception.Message.Substring(0, maxMessageLength - 1) + "…"
: failedState.Exception.Message;
// If attempt number is less than max attempts, we should
// schedule the job to run again later.
var reason = $"Retry attempt {retryAttempt} of {Attempts}: {exceptionMessage}";
context.CandidateState = new EnqueuedState { Reason = reason };
if (LogEvents)
{
Logger.WarnException(
$"Failed to process the job '{context.BackgroundJob.Id}': an exception occurred. Retry attempt {retryAttempt} of {Attempts} will be performed in {delay}.",
failedState.Exception);
}
}
But this code does not do any moving of the job. I have quite long queues, and I don’t want to retry the job immediately, but I also don’t want to schedule the job. What I would like is to remove the job from the queue, and readd the job from the queue. So I tried to alter the OnStateApplied functionality, but what to do now?
public void OnStateApplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
{
if (context.NewState is ScheduledState &&
context.NewState.Reason != null &&
context.NewState.Reason.StartsWith("Retry attempt"))
{
transaction.AddToSet("retries", context.BackgroundJob.Id);
} else if (context.NewState is EnqueuedState &&
context.NewState.Reason != null &&
context.NewState.Reason.StartsWith("Retry attempt")) {
//remove and reinsert into queueit is in
var originalQueue = JobHelper.FromJson<string>(context.Connection.GetJobParameter(context.BackgroundJob.Id, "OriginalQueue")) ?? EnqueuedState.DefaultQueue;
if (originalQueue != null)
{
transaction.
transaction.AddToQueue(originalQueue, context.BackgroundJob.Id);
}
}
}