coravel icon indicating copy to clipboard operation
coravel copied to clipboard

How to control the time of two scheduled tasks

Open dallasbeek opened this issue 4 years ago • 2 comments

Describe the bug I have a pull/push from database scenario where I would like to run them every minute but give the pull a slight head start. (In my case the pull database is still the master). I have the below code but when I check the database they are running at the same time. I've also tried PreventOverlapping but that seems to only work on itself. Note: in my scenario it's not required that Pull finishes first, I just want to give it a slight headstart, (Something like EveryMinuteOn(10)) would work perfectly for me.

Here is my code I have tried.

                scheduler.OnWorker("PullPushTasks");
                scheduler
                    .Schedule<LegacyPullTask>()
                    .EveryMinute();

                scheduler
                    .Schedule<LegacyPushTask>()
                    .EveryMinute();

Affected Coravel Feature Scheduling

Expected behaviour Be able to control when two related tasks start

dallasbeek avatar Apr 15 '20 15:04 dallasbeek

Thanks for reaching out! Given how coravel is implemented, I don't think something like EveryMinuteOn() would be that straightforward.

That being said, this does seem like a "unique" case.

I'd recommend doing something like putting them both in the same invocable and just run the push logic on another thread after you've gotten to a "safe" point within the logic of the pull.

Pseudo logic:

// Pull database stuff
var task = Thread.Run(async () => {
    // Do the push logic
});
// Do some more pull logic while the push logic runs in parallel.
await task; // Makes sure you can "see" any errors from the push task, etc.

return;

What are your thoughts around something that?

jamesmh avatar Apr 17 '20 02:04 jamesmh

My need for this isn't enough for me to put together a pull request but I do think the following would work. In ScheduledEvent class the implementation of the method looks like this.

 public IScheduledEventConfiguration EveryMinuteAt(int seconds)
{
    this._secondsInterval = seconds;
    this._isScheduledPerSecond = true;
    this._expression = new CronExpression($"* * * * *");
    return this;
}

Then change IsDue method on seconds check to check not only weekdays but the entire expression.

    if (this._isScheduledPerSecond)
    {
	var isSecondDue = this.IsSecondsDue(zonedNow);
	return isSecondDue && this._expression.IsDue(zonedNow);
    }

dallasbeek avatar Apr 21 '20 23:04 dallasbeek