filterContext.Canceled

I use this attribute to disable multiple jobs queued with same parameters at the same time. One “issue” I have with it is that cancelled jobs are also put in succeeded tab on dashboard. Is it possible to have them go to deleted tab?

public class DisableMultipleQueuedItemsAttribute : JobFilterAttribute, IServerFilter, IElectStateFilter
{
    private static readonly TimeSpan _lockTimeout = TimeSpan.FromSeconds(10);
    private static readonly List<string> _releaseStates = new List<string> { DeletedState.StateName, FailedState.StateName };

    public void OnPerforming(PerformingContext filterContext)
    {
        if (!AddFingerprintIfNotExists(filterContext.Connection, filterContext.BackgroundJob))
        {
            filterContext.Canceled = true;
        }
    }

    public void OnPerformed(PerformedContext filterContext)
    {
        // If job finished with success we remove lock.
        if (filterContext.Exception == null || filterContext.ExceptionHandled)
        {
            RemoveFingerprint(filterContext.Connection, filterContext.BackgroundJob);
        }
    }

    public void OnStateElection(ElectStateContext context)
    {
        // If job is going to release state and it isn't in failed state we release the lock.
        // if job is already in failed state we don't release lock because lock can be from a running job, failed job already had it's lock removed.
        if (_releaseStates.Contains(context.CandidateState.Name) && context.CurrentState != FailedState.StateName)
        {
            RemoveFingerprint(context.Connection, context.BackgroundJob);
        }
    }

    private static bool AddFingerprintIfNotExists(IStorageConnection connection, BackgroundJob job)
    {
        using (connection.AcquireDistributedLock(GetFingerprintLockKey(job), _lockTimeout))
        {
            var fingerprint = connection.GetAllEntriesFromHash(GetFingerprintKey(job));

            if (fingerprint != null && fingerprint.ContainsKey("Timestamp"))
            {
                // Actual fingerprint found, returning.
                return false;
            }

            // Fingerprint does not exist, it is invalid (no `Timestamp` key),
            // or it is not actual (timeout expired).
            connection.SetRangeInHash(
                GetFingerprintKey(job),
                new Dictionary<string, string>
                {
                    { "Timestamp", DateTimeOffset.UtcNow.ToString("o") }
                });

            return true;
        }
    }

    private static string GetFingerprint(BackgroundJob job)
    {
        var parameters = string.Empty;
        if (job.Job.Args != null)
        {
            parameters = string.Join(".", job.Job.Args);
        }

        if (job.Job.Type == null || job.Job.Method == null)
        {
            return string.Empty;
        }

        var fingerprint = $"{job.Job.Type.Name}.{job.Job.Method.Name}.{parameters}";

        return Helpers.GetSHA256(fingerprint);
    }

    private static string GetFingerprintKey(BackgroundJob job)
    {
        return $"Fingerprint:{GetFingerprint(job)}";
    }

    private static string GetFingerprintLockKey(BackgroundJob job)
    {
        return $"{GetFingerprintKey(job)}:lock";
    }

    private static void RemoveFingerprint(IStorageConnection connection, BackgroundJob job)
    {
        using (connection.AcquireDistributedLock(GetFingerprintLockKey(job), _lockTimeout))
        {
            using (var transaction = connection.CreateWriteTransaction())
            {
                transaction.RemoveHash(GetFingerprintKey(job));
                transaction.Commit();
            }
        }
    }
}