Skip to content
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

Cron - Not running multiple instances of a job #2

Open
y2k4life opened this issue Mar 22, 2023 · 2 comments
Open

Cron - Not running multiple instances of a job #2

y2k4life opened this issue Mar 22, 2023 · 2 comments

Comments

@y2k4life
Copy link

This is not an elaborate solution, but it works (in theory). You can't choose to have multiple instances running or not. I just assumed not to have multiple instances running regardless. I assumed this is not required unless you are running a job every minute or two.

I added a field to the scheduler that tracks the Task returned by job.Run(stoppingToken);. On ever tick check the list for completed tasks and clear them. Prior to running a job skip if it is on the list of running jobs.

I'm sure this might need some tweaking this was my first attempt at it.

private Dictionary<string, Task> _runningJobs;

.
.
.

// Clear completed jobs
foreach (var key in _runningJobs.Keys)
{
    if (_runningJobs[key].IsCompleted)
    {
        _runningJobs[key].Dispose();
        _runningJobs.Remove(key);
    }
}

// Run jobs that are in the map
RunActiveJobs(runMap, now, stoppingToken);

.
.
.

foreach (var run in currentRuns)
{

    // We are sure (thanks to our extension method)
    // that the service is of type ICronJob
    var job = (ICronJob)_serviceProvider.GetRequiredService(run);
    string jobName = job.GetType().Name;

    // Continue to next job if job is already running
    if (_runningJobs.ContainsKey(jobName))
    {
        continue;
    }

    // We don't want to await jobs explicitly because that
    // could interfere with other job runs
    var task = job.Run(stoppingToken);

    // Add task to running jobs
    _runningJobs.Add(jobName, task);
}
@linkdotnet
Copy link
Owner

I don't even think that the solution is "not an elaborate" as you put it. I would do the same and track the running tasks, which gives you the flexibility to:

  • Have only one task running
  • Or have n tasks running
  • Implement behavior like: "If I start a new task, the old should be cancelled"

I guess I would refactor this into its own class, but the underlying idea would be the same.
Small nitpick: You don't have to Dispose tasks in general (99% of cases). There is a nice article from Stephan Toub: https://devblogs.microsoft.com/pfxteam/do-i-need-to-dispose-of-tasks/

@y2k4life
Copy link
Author

I was wondering about the disposeing of a task, I backed that out. The additional features sound great and I would assume would be set when registering the job. Not only when to run the task, but how many.

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

No branches or pull requests

2 participants