Monday, February 21, 2022

[SOLVED] How can we allow user to set a cron JOB from frontend in Laravel?

Issue

I have a setting section in my laravel application. In this section I have a setting for defining a sync time. So the user can set their preferred time for sync data from laravel application to a third party CRM(Salesforce).

For now, I am storing a sync time into Database table. Now I want to run a cron JOB at that time for a particular user.

I have already created a cron job script and the cron job script is working fine. I am able to test cron job manually I just need to automate it with user setting(Preferred time). My Cron JOB URL https://my-domain.org/cronjob?user_id=101

I tried to use laravel scheduling but this not fulfillig my requirement.

Is there any other better solution available at laravel?


Solution

There is some information missing but I try to assume a few things to hopefully propose a working solution using the Laravel scheduler.


Assuming you store the time at which the CRON runs in the database as 01:00 for 1 o'clock in the night you could do the following:

protected function schedule(Schedule $schedule)
{
    User::query()->whereNotNull('cron_time')->each(function (User $user) use ($schedule) {
        $schedule->command('app:import', ['user_id' => $user->id])
                 ->withoutOverlapping() // prevents running the same command (+ parameters) twice at the same time, should only be a problem if the command can run > 24 hours, but still a safe thing to do
                 ->dailyAt($user->cron_time);
    });
}
  • I dreamed up that you stored the information on the User model
  • That you used a flag in the database called cron_time which contains the 01:00 or is null if the cron is disabled
  • The cron needs to run daily at that user supplied time
  • The import command is called app:import and is a console command that accept a user_id argument with the user id to run the import for

This might help you adapt the above to how it's structured in you own app.


If you want to use queued jobs to execute the imports you could also create the app:import CLI command to just dispatch that job instead of actually running the import. Depending on the amount of imports it might be a good idea to prevent long running scheduler commands and have the ability to retry and have a timeout.


Another option could also be to have a daily scheduled command that dispatches jobs to the queue scheduled to run at a specific time (which does not work with the SES driver). For more about that see: https://laravel.com/docs/5.8/queues#delayed-dispatching.



Answered By - Alex Bouma
Answer Checked By - Gilberto Lyons (WPSolving Admin)