I want to schedule a job (Task1
) to be run every 5 seconds. I have the following code:
class Kernel extends ConsoleKernel
{
protected function schedule(Schedule $schedule)
{
$schedule->job(new Task1)->everyFiveSeconds(); // <----- This is the line in question
$schedule->job(new Task2)->everyMinute();
$interval = DB::table('settings')->where('key', 'interval')?->value ?? 5;
$schedule->job(new Task3)->cron(StringHelper::cron24($interval));
}
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
I monitor the jobs on Telescope. The job runs smoothly every 5 seconds for approximately 40 seconds (8 cycles). However, it then skips about 4 cycles around the zero-second mark. For example
2024-08-28 06:47:24 Running [AppJobsTask1] ........ 9ms DONE
2024-08-28 06:47:29 Running [AppJobsTask1] ........ 7ms DONE
2024-08-28 06:47:34 Running [AppJobsTask1] ........ 7ms DONE
2024-08-28 06:47:39 Running [AppJobsTask1] ....... 10ms DONE
2024-08-28 06:47:44 Running [AppJobsTask1] ....... 10ms DONE
2024-08-28 06:47:49 Running [AppJobsTask1] ........ 7ms DONE
2024-08-28 06:47:54 Running [AppJobsTask1] ....... 12ms DONE
2024-08-28 06:47:59 Running [AppJobsTask1] ........ 9ms DONE
2024-08-28 06:48:22 Running [AppJobsTask1] ...... 314ms DONE <--- a jump here
2024-08-28 06:48:22 Running [AppServicesTask2] 11ms DONE
2024-08-28 06:48:22 Running [AppServicesTask3] 13ms DONE
2024-08-28 06:48:27 Running [AppJobsTask1] ........ 9ms DONE
2024-08-28 06:48:32 Running [AppJobsTask1] ........ 8ms DONE
2024-08-28 06:48:37 Running [AppJobsTask1] ........ 6ms DONE
2024-08-28 06:48:42 Running [AppJobsTask1] ........ 8ms DONE
2024-08-28 06:48:47 Running [AppJobsTask1] ........ 8ms DONE
2024-08-28 06:48:52 Running [AppJobsTask1] ........ 6ms DONE
2024-08-28 06:48:57 Running [AppJobsTask1] ........ 5ms DONE
2024-08-28 06:49:11 Running [AppJobsTask1] ...... 170ms DONE <--- a jump here
2024-08-28 06:49:11 Running [AppServicesTask2] 17ms DONE
2024-08-28 06:49:16 Running [AppJobsTask1] ........ 7ms DONE
2024-08-28 06:49:21 Running [AppJobsTask1] ........ 7ms DONE
2024-08-28 06:49:26 Running [AppJobsTask1] ....... 21ms DONE
2024-08-28 06:49:31 Running [AppJobsTask1] ....... 12ms DONE
2024-08-28 06:49:36 Running [AppJobsTask1] ....... 14ms DONE
2024-08-28 06:49:41 Running [AppJobsTask1] ........ 9ms DONE
Task1
runs in less than 1 second. We use Vapor serverless architecture and SQS on AWS.
When I change the duration to 1 minute (everyMinute
), the task runs perfectly well at the exact 1 minute mark.
When I change the duration fo 15 seconds (everyFifteenSeconds
), the job is run correctly every 15 seconds.
When I remove the other two tasks (Task2
and Task3
), the 5-second task runs a bit better, but still jumps at the minutes.
2024-08-28 07:21:31 Running [AppJobsTask1] ........ 7ms DONE
2024-08-28 07:21:36 Running [AppJobsTask1] ....... 13ms DONE
2024-08-28 07:21:41 Running [AppJobsTask1] ........ 8ms DONE
2024-08-28 07:21:46 Running [AppJobsTask1] ........ 5ms DONE
2024-08-28 07:21:51 Running [AppJobsTask1] ........ 8ms DONE
2024-08-28 07:21:56 Running [AppJobsTask1] ........ 6ms DONE
2024-08-28 07:22:11 Running [AppJobsTask1] ....... 91ms DONE <--- a jump here
2024-08-28 07:22:16 Running [AppJobsTask1] ........ 7ms DONE
2024-08-28 07:22:21 Running [AppJobsTask1] ........ 7ms DONE
2024-08-28 07:22:26 Running [AppJobsTask1] ........ 7ms DONE
2024-08-28 07:22:31 Running [AppJobsTask1] ........ 9ms DONE
2024-08-28 07:22:36 Running [AppJobsTask1] ........ 8ms DONE
2024-08-28 07:22:41 Running [AppJobsTask1] ........ 8ms DONE
2024-08-28 07:22:46 Running [AppJobsTask1] ........ 8ms DONE
2024-08-28 07:22:51 Running [AppJobsTask1] ........ 6ms DONE
2024-08-28 07:22:56 Running [AppJobsTask1] ........ 7ms DONE
2024-08-28 07:23:08 Running [AppJobsTask1] ....... 88ms DONE <--- a jump here
2024-08-28 07:23:13 Running [AppJobsTask1] ........ 9ms DONE
2024-08-28 07:23:18 Running [AppJobsTask1] ........ 5ms DONE
2024-08-28 07:23:23 Running [AppJobsTask1] ........ 5ms DONE
Any ideas what could be the reason(s)? Or how can I solve the issue? Thanks.
2
Answers
After a lot of searching, apparently it is due to the way that Vapor handles sub-minute jobs. It uses AWS EventBridge. EventBridge is launched at every minute. This takes time to become fully functional. Hence, missing some seconds at the beginning of each minute. Please see this blog for details https://blog.laravel.com/vapor-sub-minute-scheduled-tasks
Basically you need to have this in your environment:
Additionally you need to make sure:
Maybe garbage collection is getting into action – https://www.php.net/manual/en/features.gc.performance-considerations.php#features.gc.performance-considerations.slowdowns
Try to disable it and experiment more.