I’m trying to limit some of the jobs being requested if the job is already enqueued. I thought hangfire funneled jobs through a “pipeline” state machine of Enqueued, Processing, Success/Fail so it would be possible in the attribute.
I cobbled this together real fast to prove the concept but looking at the logging and hangfire front end, it still enqueues when one appears to already be enqueued. I think this is the main issue maybe.
I’m trying to use a static hash and maybe that’s not a good idea…?..?..
private static HashSet<string> _items
It will get into setting the state to delete, but only if i do something like a loop and enqueue 1000 jobs in a second.
Any suggestions or better ideas?
void IElectStateFilter.OnStateElection(ElectStateContext context)
{
Logger.TraceData(TraceEventType.Information, 0, context?.BackgroundJob?.Id + " State: " + context.CandidateState.Name + " Method: OnStateElection");
var resourceKey = String.Format("{0}.{1}", context.BackgroundJob.Job.Type.FullName, context.BackgroundJob.Job.Method.Name);
var enqueueKey = String.Format("{0}.{1}", "Enqueued", resourceKey);
var processingKey = String.Format( "{0}.{1}", "Processing", resourceKey);
var failedState = context.CandidateState as Hangfire.States.FailedState;
if (failedState != null)
{
Logger.TraceData(TraceEventType.Information, 0, context.BackgroundJob.Id + " FailedState");
_items.Remove(processingKey);
}
else
{
var succeededState = context.CandidateState as Hangfire.States.SucceededState;
if (succeededState != null)
{
Logger.TraceData(TraceEventType.Information, 0, context?.BackgroundJob?.Id + " SucceededState");
_items.Remove(processingKey);
}
else
{
var processingState = context.CandidateState as Hangfire.States.ProcessingState;
if (processingState != null)
{
Logger.TraceData(TraceEventType.Information, 0, context?.BackgroundJob?.Id + " ProcessingState");
if (_items.Contains(processingKey))
{
Logger.TraceData(TraceEventType.Information, 0, context?.BackgroundJob?.Id + " ProcessingState to EnqueuedState");
context.CandidateState = new EnqueuedState();
}
else
{
Logger.TraceData(TraceEventType.Information, 0, context?.BackgroundJob?.Id + " ProcessingState Add to Qeueue");
if (_items.Contains(enqueueKey))
{
_items.Remove(enqueueKey);
}
_items.Add(processingKey);
}
}
else
{
var enqueuedState = context.CandidateState as Hangfire.States.EnqueuedState;
if (enqueuedState != null)
{
Logger.TraceData(TraceEventType.Information, 0, context?.BackgroundJob?.Id + " EnqueuedState");
if (_items.Contains(enqueueKey))
{
Logger.TraceData(TraceEventType.Information, 0, context?.BackgroundJob?.Id + " EnqueuedState to DELETE");
context.CandidateState = new DeletedState();
}
else
{
Logger.TraceData(TraceEventType.Information, 0, context?.BackgroundJob?.Id + " EnqueuedState Add");
_items.Add(enqueueKey);
}
}
else
{
Logger.TraceData(TraceEventType.Information, 0, context.BackgroundJob.Id + " Final Else: " + context.CandidateState.Name);
}
}
}
}