HangfireIO / Hangfire

An easy way to perform background job processing in .NET and .NET Core applications. No Windows Service or separate process required
https://www.hangfire.io
Other
9.31k stars 1.69k forks source link

AutomaticRetryAttribute work only on interface #904

Open Centurys opened 7 years ago

Centurys commented 7 years ago

I have jobs defined as interfaces in one assembly and implementation in another. My interface assembly can't use Hangfire lib dependency and I want to use AutomaticRetryAttribute on every job with different values. Job schedule and registering is done with interfaces. Is there a way to use AutomaticRetryAttribute on implementation classes? If not, would you consider as good improvement? I think if you have job business logic in implementation class, why not use job execution control logic also here.

odinserj commented 7 years ago

Consider you have the IMyJob interface and the MyJob class that implements that interface. Using current IoC containers, we can know that MyJob class exists only when trying to create an instance of the IMyJob service. Hangfire creates instances only just before invoking the target method (almost final stage of the processing pipeline). But there are a lot of other places where state filters (AutomaticRetryAttribute is one of them) are invoked, and we shouldn't create any instances of your background job there, just because it may contain some side effects.

As a workaround, you can define a wrapper interface or wrapper class that has the attribute defined. So in current architecture we shouldn't enable this behavior. But this problem appear from time to time, so I'll think about how to improve this, at least in V2.

Centurys commented 7 years ago

Thanks for the answer and acknowledgment of the problem (maybe small problem) :) When do you think or prognose V2 could be released?

As of wrapper class suggestion, wrapper class basically replace common interfaces and everyone has to use new lib with new types and hangfire reference. I'm not saying its bad, but it's not every time possible. For now on think I'm stuck with old school try catch count++ solution :)

As of easy workaround could be registering on background server "GlobalJobFilters.Filters.Add" filter with interface type, and saved on some kind of dictionary, globally but per job type. And of course maybe you think of something good in V2 with processing pipeline changes and implementation class attributes.

Anyway great library keep it going :) P.S. Did you think of spliting Hangfire.Core in Server and Client parts?

dazbradbury commented 4 weeks ago

What was the outcome of this? We just had a situation with an attribute being on an interface, but not the concrete class, causing some confusion.

Looking to find out what the correct approach is as far as Hangfire is concerned:

1) Only place attributes on the interface 2) Only place attributes on the concrete class 3) Attributes need to be on both interface and concrete class