Skip to content

Conversation

@nulltoken
Copy link
Collaborator

@nulltoken nulltoken commented Jul 6, 2025

Pull request description

PR meta checklist

  • Pull request is targeted at main branch for code
  • Pull request is linked to all related issues, if any.

Code PR specific checklist

  • My code follows the code style of this project and AspNetCore coding guidelines.
  • My change requires a change to the documentation.
    • I have updated the documentation accordingly.
  • My change requires a change to the CHANGELOG.
    • I have updated the appropriate sub section in the CHANGELOG.md.
  • I have added, updated or removed tests to according to my changes.
    • All tests passed.

@codecov
Copy link

codecov bot commented Jul 6, 2025

Codecov Report

Attention: Patch coverage is 93.13725% with 7 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...c/NCronJob/Configuration/Builder/JobRegistrator.cs 88.88% 4 Missing and 2 partials ⚠️
src/NCronJob/NCronJobExtensions.cs 50.00% 1 Missing ⚠️
Files with missing lines Coverage Δ
...NCronJob/Configuration/Builder/JobOptionBuilder.cs 100.00% <100.00%> (ø)
...Job/Configuration/Builder/NCronJobOptionBuilder.cs 93.18% <100.00%> (+4.39%) ⬆️
...CronJob/Configuration/Builder/RuntimeJobBuilder.cs 100.00% <100.00%> (ø)
src/NCronJob/Registry/JobRegistry.cs 89.28% <100.00%> (-0.10%) ⬇️
src/NCronJob/Registry/RuntimeJobRegistry.cs 98.70% <100.00%> (+0.01%) ⬆️
src/NCronJob/NCronJobExtensions.cs 95.65% <50.00%> (-2.13%) ⬇️
...c/NCronJob/Configuration/Builder/JobRegistrator.cs 88.88% <88.88%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@nulltoken nulltoken force-pushed the ntk/untyped_job_deps branch 4 times, most recently from c43eebe to 0f1df3a Compare July 6, 2025 18:28
@nulltoken
Copy link
Collaborator Author

nulltoken commented Jul 6, 2025

@linkdotnet Although not 100% ready, I'd be a taker for a first pass of review please.

  • JobRegistrator now holds the proposed V5 interface for registering jobs. The idea is to make NCronJobBuilder implement it (and delegate to JobRegistrator) during the move to v5.
  • Untyped jobs and typed jobs are now registered in a similar way
  • Untyped jobs can declare dependencies

@linkdotnet
Copy link
Member

@nulltoken
Good job!

I am fine as long as this version still works:

public NCronJobOptionBuilder AddJob(
        Delegate jobDelegate,
        string cronExpression,

I think the docs should showcase both and why both versions exist (simplicty over configurability and vice-versa). Currently, it only uses the above version.

@nulltoken
Copy link
Collaborator Author

@nulltoken Good job!

I am fine as long as this version still works:

public NCronJobOptionBuilder AddJob(
        Delegate jobDelegate,
        string cronExpression,

I think the docs should showcase both and why both versions exist (simplicty over configurability and vice-versa). Currently, it only uses the above version.

@linkdotnet I understand the need for simplicity.

However, both the docs and the README demonstrate Minimal API usage through something like

builder.Services.AddNCronJob((ILogger<Program> logger, TimeProvider timeProvider) =>
{
    logger.LogInformation("Hello World - The current date and time is {Time}", timeProvider.GetLocalNow());
}, "*/5 * * * * *");

How would you feel to keep allowing this inline usage through the AddNCronJob() IServiceCollection extension, but straighten the NCronJobBuilder to the proposed AddJob(Delegate, Action<JobOptionBuilder)?

Relevant:

@linkdotnet
Copy link
Member

That is fair if we keep both of them. I would be not onboard to drop the "string cron" version given that we want to give users the easiest setup possible to do something. Using an options builder already means the user has to know about some defaults (maybe).

Whether it is an extension or not is a different topic. I don't see the necessity here, given that everything is in one project anyway. It might make sense to "refactor" them out into a separate package.

That said, can you add some docs around the new builder. When to use (aka if you need more fine-grained control).

@nulltoken
Copy link
Collaborator Author

@linkdotnet I've dropped the deprecations in AddNCronJob() extension and NCronJobBuilder.AddJob().
I'll work on updating the doco in the following days.

@nulltoken
Copy link
Collaborator Author

nulltoken commented Jul 10, 2025

@linkdotnet Can we at least deprecate

AddJob(
        Delegate jobDelegate,
        string cronExpression,
        TimeZoneInfo? timeZoneInfo = null,
        string? jobName = null)

and only keep the following one?

AddJob(
        Delegate jobDelegate,
        string cronExpression,
        TimeZoneInfo? timeZoneInfo = null)

I understand the need for simplicity.

But once one need a name for a job, I believe the simplicity is done and JobOptionBuilderoverload should be preferred.

Thoughts?

@linkdotnet
Copy link
Member

@linkdotnet Can we at least deprecate

AddJob(
        Delegate jobDelegate,
        string cronExpression,
        TimeZoneInfo? timeZoneInfo = null,
        string? jobName = null)

and only keep the following one?

AddJob(
        Delegate jobDelegate,
        string cronExpression,
        TimeZoneInfo? timeZoneInfo = null)

I understand the need for simplicity.

But once one need a name for a job, I believe the simplicity is done and JobOptionBuilderoverload should be preferred.

Thoughts?

But the jobName is optional, isn't it? The idea behind the job name is solely that users have a way of disabling or re-enabling them later during runtime. Dees the string? jobName hinder you in any way?

Removing it would not only mean a major breaking change API-wise but also from a feature-set point of view.

@nulltoken
Copy link
Collaborator Author

nulltoken commented Jul 13, 2025

@linkdotnet Can we at least deprecate

AddJob(
        Delegate jobDelegate,
        string cronExpression,
        TimeZoneInfo? timeZoneInfo = null,
        string? jobName = null)

and only keep the following one?

AddJob(
        Delegate jobDelegate,
        string cronExpression,
        TimeZoneInfo? timeZoneInfo = null)

I understand the need for simplicity.
But once one need a name for a job, I believe the simplicity is done and JobOptionBuilderoverload should be preferred.
Thoughts?

But the jobName is optional, isn't it?

Indeed, so for people not using it, there wouldn't be any change.

The idea behind the job name is solely that users have a way of disabling or re-enabling them later during runtime.

I understand that. And the RuntimeJobRegistry is certainly the most advanced feature in the library.
This is why I was mentioning earlier that, given this intended usage, we may no longer be in "simplicity" land.
This also explains why I'm advocating to redirect users requiring a jobName toward the AddJob() overload accepting a JobOptionBuilder.

Dees the string? jobName hinder you in any way?

Removing it would not only mean a major breaking change API-wise

Deprecating its usage for this overload would raise a warning directing the user to the recommended overload.
It would indeed be removed in v5.

but also from a feature-set point of view.

Not really as the feature would still exist through the AddJob(Delegate, Action) overload.

@nulltoken
Copy link
Collaborator Author

@linkdotnet Can we at least deprecate

AddJob(
        Delegate jobDelegate,
        string cronExpression,
        TimeZoneInfo? timeZoneInfo = null,
        string? jobName = null)

and only keep the following one?

AddJob(
        Delegate jobDelegate,
        string cronExpression,
        TimeZoneInfo? timeZoneInfo = null)

I understand the need for simplicity.
But once one need a name for a job, I believe the simplicity is done and JobOptionBuilderoverload should be preferred.
Thoughts?

But the jobName is optional, isn't it?

Indeed, so for people not using it, there wouldn't be any change.

The idea behind the job name is solely that users have a way of disabling or re-enabling them later during runtime.

I understand that. And the RuntimeJobRegistry is certainly the most advanced feature in the library. This is why I was mentioning earlier that, given this intended usage, we may no longer be in "simplicity" land. This also explains why I'm advocating to redirect users requiring a jobName toward the AddJob() overload accepting a JobOptionBuilder.

Dees the string? jobName hinder you in any way?
Removing it would not only mean a major breaking change API-wise

Deprecating its usage for this overload would raise a warning directing the user to the recommended overload. It would indeed be removed in v5.

but also from a feature-set point of view.

Not really as the feature would still exist through the AddJob(Delegate, Action) overload.

@linkdotnet Have you had the time to gather your thoughts about this deprecation proposal? 😉

@linkdotnet
Copy link
Member

Hey hey @nulltoken - sure I did have some time but also totally forgot about that :D

I am still not a fan of forcing users to supply a jobName. The middle ground would be to automatically set the name (Guid.NewGuid or similiar friends).

If the user just needs a way of triggering a job on a frequent base but don't do anything else, why having a name?

That we need this internally, might make things easier and we can add some random string, I am fair with that, but don't see much value forcing the user.

But once one need a name for a job, I believe the simplicity is done and JobOptionBuilderoverload should be preferred.

That is, to some extent true - but more because of the way the library works. For example quartz returns an object (a trigger) which you can just "disable" easily.
But fair for me, we can roll with your version and deprecate the current API, so the user has to use the builder.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[V5] Allow dynamic jobs to have dependent jobs as well [V5] Align dynamic and typed job creation

3 participants