Support the ongoing development of Laravel.io →
posted 9 years ago
Jobs

In the scheduler, there is the withoutOverlapping() clause that can be used on a single job, to prevent a job from being run on its next time slot if the same job is still running from the previous time slot. It helps to protrect long-running jobs colliding.

Now, my problem is that I have two different jobs. They should run at different times (e.g. one every odd minute and the other every even minute). What I want to prevent is these two jobs from overlapping. So if the odd-minute job is still running when it is the even-minute job's turn, then it should simply miss its turn.

Is this possible using the Laravel scheduler? How do I link two separate jobs as a "without overlapping" pair?


My use-case is jobs that fetch transactions from Xero - two jobs to fetch different types of transactions. Since OAuth tokens are renewed every half an hour on Xero, I want to avoid a race condition when Xero is responding slowly and tokens for the same organisation are being renewed by two running jobs at the same time. That happened to me on Friday when Xero was having some verrrry slow connection issues. I would like to prevent this from happening again.

Last updated 3 years ago.
0

I'm not sure if this works for you, but some years ago I had something similar and I ended using a file flag, meaning a file somewhere in my system that was created by one of my jobs and deleted at the end of the process, and if it's there then the next job will wait for it to finish, checking if the file was present or not.

0

Sounds like a pid file that many operating systems use. The file contains the ID of the process that created it, so any new process that finds the file, can then check if the process really is still running or has died without removing the file. That allows a new process to take over the file if it needs to.

I was thinking something similar along the lines of database locks. I could lock a table or table row when entering an atomic part of the process (the bit that must be run without any interruption, on its own) and then release the lock at the end. If the process dies for any reason, then the database will release that lock automatically as the database connection is closed.

A more sledgehammer way to solve my problem would be to roll up the two scheduled jobs into one, and work out which bit to run within that combined job. But that then removes all the advantages of using the Laravel scheduler in the first place to handle the timings correctly.

Thanks for your suggestion - a lock file or database lock is probably what I'm going to have to use, unless there is an undocumented way to group jobs within the scheduler under a single "no overlap" (similar to the way you can group routes together, nested in many layers, and add paths, middleware etc. at any level of grouping).

Last updated 9 years ago.
0

Oooh, file locking using flock(). I'll give this a go.

This example shoes the PID files I described in action from PHP, but that's probably a little overkill for my application, but a good read.

Last updated 9 years ago.
0

Sign in to participate in this thread!

Eventy

Your banner here too?

judgej judgej Joined 4 Mar 2014

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2025 Laravel.io - All rights reserved.