Created
August 21, 2018 15:55
-
-
Save odinserj/795765787b7900d00e61a8d1c8d495f8 to your computer and use it in GitHub Desktop.
This file contains 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
using System; | |
using System.Threading.Tasks; | |
using Hangfire; | |
using Hangfire.Common; | |
using Hangfire.States; | |
using Hangfire.Storage; | |
using Microsoft.Owin.Hosting; | |
using Owin; | |
namespace ConsoleApp71 | |
{ | |
// You can use this filter to shorted the expiration time for jobs that are | |
// in the Failed -> Deleted state transition. Otherwise they will be expired | |
// in 24 hours by default. | |
public class ImmediateDeletionAttribute : JobFilterAttribute, IApplyStateFilter | |
{ | |
public void OnStateApplied(ApplyStateContext context, IWriteOnlyTransaction transaction) | |
{ | |
if (context.OldStateName == FailedState.StateName) | |
{ | |
context.JobExpirationTimeout = TimeSpan.Zero; | |
} | |
} | |
public void OnStateUnapplied(ApplyStateContext context, IWriteOnlyTransaction transaction) | |
{ | |
} | |
} | |
public class ThrowingService | |
{ | |
[ImmediateDeletion, AutomaticRetry(Attempts = 0)] | |
public void ThrowingMethod() | |
{ | |
throw new PlatformNotSupportedException(); | |
} | |
public void DeleteStepByStep() | |
{ | |
const int batchCount = 1000; | |
var storage = JobStorage.Current; | |
var monitoring = storage.GetMonitoringApi(); | |
var stateChanger = new BackgroundJobStateChanger(); | |
var failedJobs = monitoring.FailedJobs(0, batchCount); | |
if (failedJobs == null || failedJobs.Count == 0) | |
{ | |
return; | |
} | |
using (var connection = storage.GetConnection()) | |
{ | |
foreach (var failedJob in failedJobs) | |
{ | |
stateChanger.ChangeState(new StateChangeContext( | |
storage, | |
connection, | |
failedJob.Key, | |
new DeletedState { Reason = "Removed automatically" }, | |
FailedState.StateName | |
)); | |
} | |
} | |
if (failedJobs.Count == batchCount) | |
{ | |
BackgroundJob.Enqueue<ThrowingService>(x => x.DeleteStepByStep()); | |
} | |
} | |
} | |
public class Startup | |
{ | |
public void Configuration(IAppBuilder app) | |
{ | |
app.UseHangfireDashboard(""); | |
app.UseHangfireServer(); | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
GlobalConfiguration.Configuration | |
.UseRedisStorage() | |
.UseFilter(new ImmediateDeletionAttribute()); | |
Parallel.For(0, 1000000, _ => { BackgroundJob.Enqueue<ThrowingService>(x => x.ThrowingMethod()); }); | |
// Uncommend the following line once all the jobs are in the failed state | |
// to start the deletion process. | |
//BackgroundJob.Enqueue<ThrowingService>(x => x.DeleteStepByStep()); | |
using (WebApp.Start<Startup>("http://localhost:12345")) | |
{ | |
Console.ReadLine(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment