Hangfire.Thottling not ideal design with ThrottlingAttribute

queues
Tags: #<Tag:0x00007f49a1303b98>

#1

Having ThrottlingAttribute depend on jobFilterProvider in its initialization and have the default constructor look for a static JobFilterProvider is not a good design

Why?

From documentation I’ve understood that UseThrottling method globally is optional, but actually is not so because that one initializes the shared static variable for JobFilterProvider for ThrottlingAttribute. So you cannot use just ThrottlingAttribute without calling the other.

Secondly you may use ThrottlingAttribute on a job class that’s declared in a service that will not actually execute the background work but just schedules some background work. You cannot do that because UseThrottling must be initialized in all such projects. Behavior description is not separated from behavior implementation properly in this case.


#2

I agree that implementation is tricky, but was an inevitable evil to allow multiple instances of the ThrottlerAttribute, only a single instance of the ThrottlingAttribute and better error messages when configuration was wrong (call to UseThrottling is missing, for example). Things will be changed in Hangfire 2.0, where dependency injection is planned to be everywhere.

A call to UseThrottling is required before the use of any throttler. I will check the docs, but could you also share the sentence that’s confusing?

Could you give some code samples or rephrase it? It looks like you are willing to not to call the UseThrottling method in some of your projects, but I can miss the point.


#3

The confusion for me was in the following paragraph, where it states can be applied either locally, which in my understanding is per job method or globally.

Blockquote
Throttling happens when throttling condition of one of the applied throttlers wasn’t satisfied. It can be configured either globally or locally, and default throttling action is to schedule background job to run one minute (also can be configured) later. After acquiring a throttler, it’s not released until job is moved to a final state to prevent part effects.

And the thing that further maintained the confusion was that:

  • UseThrottling method and ThrottlingAttribute had many parameters in common.
  • with Throttling library beta version 1 this worked without issues but when I’ve updated to version 1.0.3 it stopped working leading to serious production issues on my end.

A clarification statement would be nice in documentation to say no matter what you want to throttle a single job or all of them you must call UseThrottling method regardless.

But anyway I’ve updated my code to apply UseThrottling in initialization phase of each of my startup projects and works now.

Thanks for your asnwer


#4

Do you have an example of this? I am confused about where I should setup the ThrottlingManager.