Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save minhhungit/8db781294d2fd1cb37ceb539e9b4b0d4 to your computer and use it in GitHub Desktop.
Save minhhungit/8db781294d2fd1cb37ceb539e9b4b0d4 to your computer and use it in GitHub Desktop.
SkipWhenPreviousJobIsRunningAttribute.cs
// Zero-Clause BSD (more permissive than MIT, doesn't require copyright notice)
//
// Permission to use, copy, modify, and/or distribute this software for any purpose
// with or without fee is hereby granted.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
// OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
// THIS SOFTWARE.
using System;
using System.Collections.Generic;
using Hangfire.Client;
using Hangfire.Common;
using Hangfire.States;
using Hangfire.Storage;
namespace ConsoleApp28
{
public class SkipWhenPreviousJobIsRunningAttribute : JobFilterAttribute, IClientFilter, IApplyStateFilter
{
public void OnCreating(CreatingContext context)
{
var connection = context.Connection as JobStorageConnection;
// We can't handle old storages
if (connection == null) return;
// We should run this filter only for background jobs based on
// recurring ones
if (!context.Parameters.ContainsKey("RecurringJobId")) return;
var recurringJobId = context.Parameters["RecurringJobId"] as string;
// RecurringJobId is malformed. This should not happen, but anyway.
if (String.IsNullOrWhiteSpace(recurringJobId)) return;
var running = connection.GetValueFromHash($"recurring-job:{recurringJobId}", "Running");
if ("yes".Equals(running, StringComparison.OrdinalIgnoreCase))
{
context.Canceled = true;
}
}
public void OnCreated(CreatedContext filterContext)
{
}
public void OnStateApplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
{
if (context.NewState is EnqueuedState)
{
var recurringJobId = JobHelper.FromJson<string>(context.Connection.GetJobParameter(context.BackgroundJob.Id, "RecurringJobId"));
if (String.IsNullOrWhiteSpace(recurringJobId)) return;
transaction.SetRangeInHash(
$"recurring-job:{recurringJobId}",
new[] { new KeyValuePair<string, string>("Running", "yes") });
}
else if ((context.NewState.IsFinal && !FailedState.StateName.Equals(context.OldStateName, StringComparison.OrdinalIgnoreCase)) ||
(context.NewState is FailedState))
{
var recurringJobId = JobHelper.FromJson<string>(context.Connection.GetJobParameter(context.BackgroundJob.Id, "RecurringJobId"));
if (String.IsNullOrWhiteSpace(recurringJobId)) return;
transaction.SetRangeInHash(
$"recurring-job:{recurringJobId}",
new []{ new KeyValuePair<string, string>("Running", "no") });
}
}
public void OnStateUnapplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
{
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment