Visitar URL original
Cron - Not running multiple instances of a job · Issue #2 · linkdotnet/BlogExamples · GitHub
Skip to content

Cron - Not running multiple instances of a job #2

Open

Description

@y2k4life

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);
}

Activity

  1. linkdotnet commented on Mar 22, 2023

    @linkdotnet
    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/

  2. y2k4life commented on Mar 22, 2023

    @y2k4life
    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions