0

I am using Laravel Task Scheduling and I scrape data from bunch of urls in a for loop. That's why I don't know for sure when one cycle finishes. I tried to setup a for loop in the Kernel's schedule() method as mentioned in this question but it doesn't seem to work efficiently.

protected function schedule(Schedule $schedule)
{
   $schedule->command('catalog:update')->everyMinute();
   sleep(5);
   $schedule->command('catalog:update')->everyMinute();
   sleep(5);
}

What I want to achieve is that detect when task is finished, and run it again accordingly. Like creating a never-ending loop, but they shouldn't overlap because it won't let the previous scraping finish I think (am I right?).

So I want something like:

protected function schedule(Schedule $schedule)
{
   $schedule->command('catalog:update');

   // Detect when completed {
   // run it again. Detect when completed again, etc as a loop. 
   //}

}
Community
  • 1
  • 1
senty
  • 12,385
  • 28
  • 130
  • 260

1 Answers1

0

You can't loop in the schedule method. All that is supposed to do is define a cron schedule. The actual command is not run inside the schedule method.

You can make the command run every minute and set it to not overlap. That way it will attempt to start the command every minute, but it will skip it if the previous attempt is still running.

protected function schedule(Schedule $schedule)
{
    $schedule->command('catalog:update')->everyMinute()->withoutOverlapping();
}
jfadich
  • 6,110
  • 2
  • 20
  • 31
  • What I want to achieve is detect when the job is completed and re-run it. And keep it in a loop. Is it better to do it in handle as `task(); sleep(5) // x5` ? – senty Mar 13 '17 at 22:15
  • @senty Why is doing it every minute not good enough? You can't do that with the task scheduling. You could use a queue. Do all of the work in a queueable job. Then once the job is completed have it add a new instance to the queue. – jfadich Mar 13 '17 at 22:17
  • @senty The actual work is NOT done in the schedule method. Sleeping there will do you no good. I think you're misunderstanding what the task scheduler is used for. – jfadich Mar 13 '17 at 22:18
  • Where to start for researching for the queue? Is it setting a method and trigger it once, and keep it on the loop forever? Maybe it is what I should use instead of task scheduling as you said. – senty Mar 13 '17 at 22:19
  • @senty The [documentation](https://laravel.com/docs/5.1/queues) is always a good place to start. Doing it this way you would add the job to the queue once then every time it completes it adds itself back to the queue effectively running indefinitely as long as it never fails. – jfadich Mar 13 '17 at 22:21
  • oh, then I should use that instead! perfect! thanks a lot – senty Mar 13 '17 at 22:22
  • Just a quick question. Let's say I have this function that I need to trigger once manually and it runs forever in a loop. I understand I will need to dispatch the job once and rerun the job when the job is done. But where should I make the first trigger? – senty Mar 13 '17 at 22:44
  • 1
    @senty That's up to you. One way to do it would create a command that simply dispatches the first job. Then run that command once as part of your deployment process. – jfadich Mar 13 '17 at 22:48
  • Agree that this might be better off in the queue. Another option would be to use supervisor to keep your catalog:update command running. You can configure supervisor to run the command again when it exits. – ShaunUK Mar 14 '17 at 11:41