Last active
March 5, 2025 15:57
-
-
Save Gh61/2cac20b443f29c53259f2d6cd0d0af64 to your computer and use it in GitHub Desktop.
An attribute that prevents processing a Hangfire job that is part of recurring job currently in the Retry state.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// An attribute that prevents processing a Hangfire job that is part of recurring job currently in the Retry state. | |
/// </summary> | |
/// <remarks> | |
/// This attribute is intended for recurring tasks only. If used on any other type of task, an exception will be thrown. | |
/// </remarks> | |
public class SkipRetryingRecurrentJobAttribute : JobFilterAttribute, IServerFilter | |
{ | |
private const string recurringJobId = "RecurringJobId"; | |
public void OnPerforming(PerformingContext context) | |
{ | |
var recurringName = context.GetJobParameter<string>("RecurringJobId"); | |
if (string.IsNullOrEmpty(recurringName)) | |
{ | |
throw new InvalidOperationException(nameof(SkipConcurrentTaskExecutionAttribute) + " can be used only for recurring jobs."); | |
} | |
if (!(context.Connection is JobStorageConnection storage)) | |
{ | |
throw new InvalidOperationException($"Only {nameof(JobStorageConnection)} is supported."); | |
} | |
var retryJobIds = storage.GetAllItemsFromSet("retries"); | |
foreach (var retryJobId in retryJobIds) | |
{ | |
// never resolve current job | |
if (retryJobId == context.BackgroundJob.Id) | |
continue; | |
// get the name of reccuring job from the retry job Id | |
var retryJobRecurringName = DeserializeJobParameterString(storage.GetJobParameter(retryJobId, recurringJobId)); | |
// if we're trying to start new job with the same recurring name as in retry set, cancel the run | |
if (retryJobRecurringName == recurringName) | |
{ | |
context.Canceled = true; | |
} | |
} | |
} | |
public void OnPerformed(PerformedContext context) | |
{ | |
} | |
private static string DeserializeJobParameterString(string value) | |
{ | |
if (string.IsNullOrEmpty(value)) | |
return value; | |
// if it starts and ends with quotes, get rid of them | |
if (value.StartsWith("\"") && value.EndsWith("\"")) | |
{ | |
return value.Substring(1, value.Length - 2); | |
} | |
// nothing here | |
return value; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment