Add withoutOverlapping
$schedule->job(new MyJobName())->everyMinute()->withoutOverlapping();
More details: https://laravel.com/docs/10.x/scheduling#preventing-task-overlaps
hello guys. I have been researching this bug for hours, without any luck.
I have a problem, I dispatch a job on scheduler every 1 minute, but sometimes I can see the job being twice on the queue. The jobs are running from different queue workers at the same time. How is that possible?
I also use ShouldBeUnique interface on my job.
and on my scheduler I have:
$schedule->job(new MyJobName())->everyMinute();
Can someone help me, because I am so confused. Am i doing something wrong here?
Add withoutOverlapping
$schedule->job(new MyJobName())->everyMinute()->withoutOverlapping();
More details: https://laravel.com/docs/10.x/scheduling#preventing-task-overlaps
You might need to define a key to make it unique, but ->withoutOverlapping() should suffice:
/**
* Get the unique ID for the job.
*/
public function uniqueId(): string
{
return $this->product->id;
}
@mohamedtammam @jimmyaldape i dont think its that guys. withoutOverlapping only concerns running two instances of the same scheduled task. Since the scheduler's work is over in a fraction of a second (putting the job on the queue) then they will never overlap.
@ninj4df my first investigation would be to pause the queue workers and see if this job starts to build up in the queue (sounds like it will)
sorry @jimmyaldape has the right idea, its the withoutOverlapping contract that you need to add to your job
confusing that there are two identically named functions in different places
Note that adding the contract to your job will not prevent the job being listed multiple times, but will ensure they cannot be executed at the same time by different workers
And guys what's the difference between withoutOverlapping on Schedule VS ShouldBeUnique contract on jobs? Huge note here that all my scheduled actions are queued Jobs, does it still work with jobs? And also if you can explain why ShouldBeUnique does not work on my case?
Could someone clarify that guys? Thank you a lot for your time and your answers!
withoutOverlapping on scheduled tasks just means don't start another instance of this scheduled task if a previous one is still running. You don't have any long running tasks, so this is irrelevant.
ShouldBeUnique might not work if you don't have a clear way to identify duplicate instances of the same job.
@Snapey so withoutoverlapping is irellevant on my case if I understood well? Also i have jobs not commands or callbacks on scheduler, does it afftect it somehow?
Wasn't withoutOverlapping what you suggested me before? Sorry but I lost you :D Maybe I got confused on smthing .
@Ninj4df If a job is placed on the queue, but there are no available queue workers for one minute, or a backlog on the queues, then after a minute, a second copy of the job is added to the queue.
How do you want to handle this?
The correct answer for you depends on what you hope to happen.
@Snapey I am ok with both of them :) I just want to ensure that this job is not running multiple times simultaneously. What do you suggest me?
@Ninj4df decide!
@Snapey Ok, then I prefer the second one
"perform the first job, and then when a worker picks up the second job, delete it because there is already one running."
@Ninj4df https://laravel.com/docs/11.x/queues#preventing-job-overlaps
When you add the middleware to the job, you are expected to provide an arbitrary key name which you can decide. In the example it uses the user ID but you could use a string
public function middleware(): array
{
return [new WithoutOverlapping('not-to-be-overlapping-job-name')->dontRelease()];
}
You can release the job back to the queue, but you have said your preference is to delete it, so add dontRelease
edit: struck me that you could probably just use the name of the job
public function middleware(): array
{
return [new WithoutOverlapping(get_class($this))->dontRelease()];
}
Please or to participate in this conversation.