Thursday 18 July 2019

Laravel Schedule cron job and schedule it to run every X seconds(Cron default runs it every minute) && at time zone && for different web application && command with parameter && run schedule command with parameter

Laravel schedule cron job
https://laravel.com/docs/5.8/scheduling

// Laravel schedule job at time zone
$schedule->command('report:generate')
         ->timezone('America/New_York')
         ->at('02:00')
https://laravel.com/docs/5.8/scheduling

// Laravel create a command with parameter

The {--order} option (without an = sign) declares a switch option, which takes no arguments. If the switch option is present, its value equals true, and, when absent, false (--help is like a switch—no argument needed).
When we provide an argument on the command line for this option, the console framework cannot match the input to an option with an argument, so it throws the error as shown in the question.
To allow the option to accept an argument, change the command's $signature to:
protected $signature = 'order:check {--order=}'
Note the addition of the equal sign after --order. This tells the framework that the --order option requires an argument—the command will throw an exception if the user doesn't provide one.
If we want our command to accept an option with or without an argument, we can use a similar syntax to provide a default value:
protected $signature = 'order:check {--order=7}'
...but this doesn't seem useful for this particular case.
After we set this up, we can call the command, passing an argument for --order. The framework supports both formats:
$ php artisan order:check --order=7 
$ php artisan order:check --order 7 
...and then use the value of order in our command:
$orderNumber = $this->option('order');  // 7
https://stackoverflow.com/questions/46670304/laravel-command-only-optional-argument


// Multiple parameter
protected $signature = 'order:check {--order=} {--parameter2==}
$paramter2= $this->option('parameter2');  // 
// If parameter specified in input, and there is no such paramter input, 
$paramter2= $this->option('parameter2');  // will result empty

// Run command job with commands
$schedule->command('users:daysInactiveInvitation --days=30')->daily();
https://stackoverflow.com/questions/30202268/laravel-5-command-scheduler-how-to-pass-in-options

// Wtih diffent web application
* * * * * cd /path-to-your-project2 && php artisan schedule:run >> /dev/null 2>&1



 // start scheduler
vim /etc/crontab
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
// Make command class(will be created in app/console/commands

php artisan make:command <command_class_name> --command=<running_command_when_typing, informat of a:b>
// Open command_class_name file in app/console/commands/<command_class_name>.php, change descrpition

   /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'demo';
// Register your command in app  >>  Console >> Kernel.php
 /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        'App\Console\Commands\command_class_name',
    ];
// Verify command
php artisan list 
// Add your command execution logic in handle() function in command_class_name.php

 /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $totalUsers = \DB::table('users')
                  ->whereRaw('Date(created_at) = CURDATE()')
                  ->count();
    }

// Run command once 


php artisan registered:users

// Schedule command to run in app  >>  Console  >>  Kerne.php every minute
// Kernel.php

   /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
          $schedule->command('registered:users')
                   ->everyMinute();
    }

// Run commnad every x seconds?


By default CRON tasks are scheduled in minimal period 1 minute, but there is workaround for your issue.
In Console Kernel you should do something like this:
/**
 * Define the application's command schedule.
 *
 * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
 * @return void
 */
protected function schedule(Schedule $schedule)
{
     $schedule->command('your_command:run', ['--delay'=> 0])->everyMinute();
     $schedule->command('your_command:run', ['--delay'=> 30])->everyMinute();
}
In your Command class you should define the $signature variable that can take the delay parameter.
/**
 * The name and signature of the console command.
 *
 * @var string
 */
protected $signature = 'your_command:run {--delay= : Number of seconds to delay command}';
In the handle method you should read value of this parameter and sleep this task for specific number of second using built-in sleep() function.
/**
 * Execute the console command.
 *
 * @return mixed
 */
public function handle()
{
    // code
    sleep(intval($this->option('delay')));
}
This solution will run your task every 30 seconds, you can multiply number of task with different delay. In this case you need to edit schedule method in Kernel class.
https://stackoverflow.com/questions/36354181/can-run-a-task-every-x-second-with-laravel
https://appdividend.com/2018/03/01/laravel-cronjob-scheduling-tutorial/
https://laravel.com/docs/5.8/scheduling

No comments:

Post a Comment