Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel schedular: execute a command every second

Tags:

php

cron

laravel

I have a project that needs to send notifications via WebSockets continuously. It should connect to a device that returns the overall status in string format. The system processes it and then sends notifications based on various conditions.

Since the scheduler can repeat a task as early as a minute, I need to find a way to execute the function every second.

Here is my app/Console/Kernel.php:

<?php    
  ...    
class Kernel extends ConsoleKernel
{
    ...
    protected function schedule(Schedule $schedule)
    {
        $schedule->call(function(){
            // connect to the device and process its response
        })->everyMinute();
    }
}

PS: If you have a better idea to handle the situation, please share your thoughts.

like image 723
Naveed Avatar asked Jul 26 '16 09:07

Naveed


3 Answers

Usually, when you want more granularity than 1 minute, you have to write a daemon.

I advise you to try, now it's not so hard as it was some years ago. Just start with a simple loop inside a CLI command:

while (true) {
    doPeriodicStuff();

    sleep(1);
}

One important thing: run the daemon via supervisord. You can take a look at articles about Laravel's queue listener setup, it uses the same approach (a daemon + supervisord). A config section can look like this:

[program:your_daemon]
command=php artisan your:command --env=your_environment
directory=/path/to/laravel
stdout_logfile=/path/to/laravel/app/storage/logs/your_command.log
redirect_stderr=true
autostart=true
autorestart=true
like image 148
Alexey Shokov Avatar answered Nov 12 '22 00:11

Alexey Shokov


for per second you can add command to cron job

*   *   *   *   *   /usr/local/php56/bin/php56 /home/hamshahr/domains/hamshahrapp.com/project/artisan taxis:beFreeTaxis 1>> /dev/null 2>&1

and in command :

<?php

namespace App\Console\Commands;

use App\Contracts\Repositories\TaxiRepository;
use App\Contracts\Repositories\TravelRepository;
use App\Contracts\Repositories\TravelsRequestsDriversRepository;
use Carbon\Carbon;
use Illuminate\Console\Command;

class beFreeRequest extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'taxis:beFreeRequest';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'change is active to 0 after 1 min if yet is 1';

    /**
     * @var TravelsRequestsDriversRepository
     */
    private $travelsRequestsDriversRepository;

    /**
     * Create a new command instance.
     * @param TravelsRequestsDriversRepository $travelsRequestsDriversRepository
     */
    public function __construct(
        TravelsRequestsDriversRepository $travelsRequestsDriversRepository
    )
    {
        parent::__construct();
        $this->travelsRequestsDriversRepository = $travelsRequestsDriversRepository;
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $count = 0;
        while ($count < 59) {
            $startTime =  Carbon::now();

            $this->travelsRequestsDriversRepository->beFreeRequestAfterTime();

            $endTime = Carbon::now();
            $totalDuration = $endTime->diffInSeconds($startTime);
            if($totalDuration > 0) {
                $count +=  $totalDuration;
            }
            else {
                $count++;
            }
            sleep(1);
        }

    }
}
like image 41
Hamid Naghipour Avatar answered Nov 12 '22 01:11

Hamid Naghipour


$schedule->call(function(){
    while (some-condition) {
        runProcess();
    }
})->name("someName")->withoutOverlapping();

Depending on how long your runProcess() takes to execute, you can use sleep(seconds) to have more fine tuning.

some-condition is normally a flag that you can change any time to have control on the infinite loop. e.g. you can use file_exists(path-to-flag-file) to manually start or stop the process any time you need.

like image 37
Inno Avatar answered Nov 12 '22 00:11

Inno