-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[V5] Drop the ability to call AddNCronJob multiple times #221
Comments
Very good point!
I would also keep it that way, it may seem redundant, but for folks that split their logic, this is a useful approach. |
What advantage is there to requiring the end user to add more boilerplate code like |
That we can make certain checks we can't do in |
Hmm, can you point me to where these checks happen. Is this something we can tackle with static analyzers (Roslyn Analyzers)? |
There are not there - hence the ticket. |
Ok. Rather than throwing an exception on a second call to |
Sure, we could do this. I know at least one user who reported that he used multiple Analyzers could be one way of tackling that. Initially, I didn't see any reason to speak against multiple |
There are indeed other reasons 😉 It's not a matter of code style. It's rather about ensuring the configuration of NCronJob is sound and safe before it's deployed in Production (in a staging slot for instance) and preventing the release from happening if that's not the case. NCronjob being a library, a user can completely abuse it. If he/she wants to call AddNCronJob() multiple times, I don't see any real reason to only consider the first call. The intent of UseNCronJob is eventually to validate that NCronJob can process production data flow in a predefined way. And would that validation lead to detection of an unsafe/ambiguous configuration, I'd prefer the startup to fail (and thus a fatal crash) rather than allowing NCronJob to wrongly process data. My two (opiniated) cents 😉 |
I see he said "Unfortunately I have decentralized my setup, where different parts of my code can just add stuff to the IOC container, including registering a job." public class HostedServicesStartup : IServiceStartup
{
/// <summary>
/// Add and configure service registrations
/// </summary>
/// <param name="services">Collection of service descriptors</param>
/// <param name="configuration">Configuration root of the application</param>
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
services.AddCronJob<CleanupPasswordRequestJob>(p =>
p.WithCronExpression("35 0 * * *"));
}
} Here |
If the order of the registrations of NCronJob is determined by where the |
That part is unclear to me. To what "order" are you referring to?
The important part is for it to run after the |
I feel that is something positive - because, as a developer, I want to control when certain things happen. |
The convention is used for middleware pipeline, which inherently has an order to it. The assumption is that all middleware is order dependent. If UseNCronJob() is not order dependent then is poses the question of why do we need that. |
That's fair, but it defeats the purpose of running at startup, basically it runs wherever you put UseNCronJob. |
Fair enough - the naming might be wrong given that you can put it somewhere or never call UseNCronJob (we could throw an exception in that instance). Today, as you can run BackgroundServices in parallel, you can’t rely that your startup jobs finished. Only everything inside the NCronJob ecosystem (which is a valid constraint). For me it stands or falls with whether or not we allow multiple AddNCronJob. If not - there is not much benefit which we couldn’t handle inside a single AddNCronJob. |
There are two mechanisms for running jobs: as an orchestration of tasks (run job1 then run job2 if job1 succeeds, otherwise handle error by doing XYZ) and as |
If we need to call
|
I think my overall conclusion would be to remove the ability of calling AddNCronJob multiple times. One call allows all the stuff we wanted without the ambiguity |
That would make things much simpler 😉 Provided this happens, and we rewire the fluent interface so that it isn't in charge of adding jobs to the registry and the DI container, this would solve all the problems (I can think of) related to analysis of the jobs orchestration configuration. The rough diagram of the execution of AddNCronJob would become
|
@nulltoken I think that is the right approach. Startup Jobs would, as it does today, run when we spin up the The only downside with this: Imagine you have a startup job that does DB seeding or migrations. As .NET offers to start jobs in parallel, other background services that use the DB might have to wait. This is a bit unfortunate. |
This could be controlled by an optional Attribute on the Job that designates order. But the whole .UseNCronJob() defeats the purpose of this. The idea of a startup job was to start it before any middleware. Once the middleware starts it very likely could need access to the DB. |
@linkdotnet I was only referring to the refactoring of AddNCronJob() implementation. I believe the lib should still offer a way to trigger the startup jobs before app start. |
I'm also for removing the ability to call .AddNCronJob() more than once. However we should address the scenario where additional jobs may be registerred outside the conventional setup. This could be done with a hooks/interceptor mechanism. |
Extracted in #247 as it could be handled in a non breaking way |
I still would tackle that on v5 - because it might break folks that have multiple registrations. |
|
It's allowed to call
AddNCronJob()
multiple times.To be effective, some consistency checks will require that all initial registrations are done. The proper place to run them would be through
UseNCronJob
.The text was updated successfully, but these errors were encountered: