Hangfire Ace
Hangfire Ace is a set of extension packages that bring advanced features for background job processing in business applications. Hangfire Ace packages are available under paid subscriptions. After purchase, you receive binaries, access to the private NuGet feed and private repository on GitHub.
Packages
Hangfire.Throttling
Limited storage support
Please note, Hangfire.Throttling package is officially supported only when using Hangfire.SqlServer, Hangfire.Pro.Redis or Hangfire.InMemory package as a job storage. We can not guarantee that throttlers will work properly with other storages, since processing guarantees heavily depend on a concrete storage implementation.
Hangfire.Throttling package contains advanced types and methods to apply concurrency and rate limits directly to our background jobs without touching any logic related to queues, workers, servers or using additional services. So you can control how many particular background jobs are running at the same point of time or within a specific time window.
Throttling is performed asynchronously by rescheduling jobs to a later time or deleting them when throttling condition is met, depending on the configured behavior. And while throttled jobs are waiting for their turn, your workers are free to process other enqueued background jobs.
See Concurrency and Rate Limiting documentation article to learn more about throttling in Hangfire. Please note that this package is about throttling and not about consistency as highlighted in the documentation. Hangfire.SqlServer and Hangfire.Pro.Redis are currently the only officially supported storages for this package.
Concurrency Limiters
Mutexes and semaphores provide a way to limit how many background jobs are allowed to run concurrently. They can be applied to a particular background jobs by using attributes, and their state changing pipeline will be altered with the throttling logic.
Here’s an example of how to use mutex to allow only a single background job to be running concurrently.
[Mutex("daily-report")] public void ProcessDailyReport() { /* ... */ }
In the following example mutexes are created dynamically, depending on a concrete orderId
. So there will be many of them with identifiers like order:1234
, order:4567
, etc., but we’ll not have multiple background jobs running at the same time for a single orderId
value.
[Mutex("order:{0}")] public void ProcessOrder(long orderId) { /* ... */ }
In the yet another example we are creating a semaphore with the limit of 20 concurrent executions…
throttlingManager.AddOrUpdateSemaphore("newsletter", new SemaphoreOptions(20));
… and applying the newly created semaphore to a background job method so we have maximum 20 background jobs that send a newsletter.
[Semaphore("newsletter")] public void SendNewsletter(int newsletterId) { /* ... */ }
Rate Limiters
Fixed window counters, sliding window counters and dynamic window counters provide a way to limit how many background job executions are allowed to run within some time interval. Background job executions that exceed the configured threshold will be rescheduled to the next window interval or deleted, depending on the configured behavior.
Different window types use different interval types, please see their documentation for details. And in the following example we are using a sliding window counter to limit how many requests issue to GitHub per hour. First we are creating a sliding window and setting its options…
throttlingManager.AddOrUpdateSlidingWindow("github", new SlidingWindowOptions( limit: 5000, interval: TimeSpan.FromHours(1), buckets: 60));
… and then applying an attribute to a background job method to make throttling work.
[SlidingWindow("github")] public void ProcessCommits(string repository) { /* ... */ }