DEV Community

Dendi Handian
Dendi Handian

Posted on • Edited on

PHP-Worker for Scheduler in Laradock

Laravel also has a scheduler functionality to run a command/task on a defined time. It can be every minute, hourly, daily, or even at a certain time. Schedulers commonly used for automatic tasks, such as reporting products/items count daily or sending daily emails. Or if you a developer, you may want to log every kind of data daily for analytic purposes.

PHP-Worker in Laradock still has one functionality to play with. Now it's time for some logging!

Prerequisites

Everything would be easier to tell if you knew about the worker first.


Prepare the scheduler test command

Let's create this artisan command:

app\Console\Commands\ExampleSchedulerTest.php :

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

class ExampleSchedulerTest extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'example:scheduler-test {logLevel} {--message=}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command for logging schedulers';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $arguments = $this->arguments();
        $options = $this->options();
        $options['message'] = $options['message'] ?? 'lorem ipsum dolor sit amet';

        switch ($arguments['logLevel']) {
            case 'emergency':
                Log::emergency($options['message']);
                break;
            case 'alert':
                Log::alert($options['message']);
                break;
            case 'critical':
                Log::critical($options['message']);
                break;
            case 'error':
                Log::error($options['message']);
                break;
            case 'warning':
                Log::warning($options['message']);
                break;
            case 'notice':
                Log::notice($options['message']);
                break;
            case 'info':
                Log::info($options['message']);
                break;
            case 'debug':
                Log::debug($options['message']);
                break;
            default:
                Log::debug($options['message']);
                break;
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

register the command and make some schedulers to the app\Console\Kernel.php :

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

use App\Console\Commands\ExampleSchedulerTest;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        ExampleSchedulerTest::class,
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('example:scheduler-test debug --message="debug everyMinute"')->everyMinute();
        $schedule->command('example:scheduler-test info --message="info everyFiveMinutes"')->everyFiveMinutes();
        $schedule->command('example:scheduler-test notice --message="notice everyTenMinutes"')->everyTenMinutes();
        $schedule->command('example:scheduler-test warning --message="warning everyFifteenMinutes"')->everyFifteenMinutes();
        $schedule->command('example:scheduler-test error --message="error everyThirtyMinutes"')->everyThirtyMinutes();
        $schedule->command('example:scheduler-test critical --message="critical hourly"')->hourly();
        $schedule->command('example:scheduler-test alert --message="alert hourlyAt 17"')->hourlyAt(17);
        $schedule->command('example:scheduler-test emergency --message="emergency daily"')->daily();
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}
Enter fullscreen mode Exit fullscreen mode

you can try the command first to make sure it works, by executing this command in your workspace bash inside your project:

php artisan example:scheduler-test debug --message="debug message"
Enter fullscreen mode Exit fullscreen mode

Setup the scheduler configuration

We still use our example directories:

- projects
  |_ my-awesome-laravel-app 
  |_ laradock
Enter fullscreen mode Exit fullscreen mode

Look for this workspace\crontab\laradock file inside laradock directory.

- projects
  |_ my-awesome-laravel-app 
  |_ laradock
     |_ workspace
        |_ crontab
           |_ laradock
Enter fullscreen mode Exit fullscreen mode

Then make sure the line inside workspace\crontab\laradock is not commented-out. The content should be like this:

* * * * * laradock /usr/bin/php /var/www/artisan schedule:run >> /dev/null 2>&1
Enter fullscreen mode Exit fullscreen mode

Further inside laradock directory, you will find this file php-worker\supervisord.d\laravel-scheduler.conf.example. Duplicate this file into my-awesome-laravel-app-scheduler.conf (the name can be different, as long as you end it with .conf).

- projects
  |_ my-awesome-laravel-app 
  |_ laradock
     |_ php-worker
        |_ supervisord.d
           |_ laravel-scheduler.conf.example
           |_ my-awesome-laravel-app-scheduler.conf
     |_ workspace
        |_ crontab
           |_ laradock
Enter fullscreen mode Exit fullscreen mode

Then modify the my-awesome-laravel-app-scheduler.conf content into:

[program:my-awesome-laravel-app-scheduler]
process_name=%(program_name)s_%(process_num)02d
command=/bin/sh -c "while [ true ]; do (php /var/www/my-awesome-laravel-app/artisan schedule:run --verbose --no-interaction &); sleep 60; done"
autostart=true
autorestart=true
numprocs=1
user=laradock
redirect_stderr=true
Enter fullscreen mode Exit fullscreen mode

And that's all for the scheduler configuration.


Run or restart the PHP-Worker container

If you haven't run the php-worker container, execute this command inside laradock directory:

docker-compose up -d php-worker
Enter fullscreen mode Exit fullscreen mode

If it's already running, you may want to restart it using this command:

docker-compose restart php-worker
Enter fullscreen mode Exit fullscreen mode

Check the Laravel Log

Look for the latest log file inside storage/logs in your laravel app, you should see the logs similar to this:

[2020-03-23 17:41:00] local.DEBUG: debug everyMinute  
[2020-03-23 17:41:02] local.INFO: info everyFiveMinutes  
[2020-03-23 17:41:04] local.NOTICE: notice everyTenMinutes  
[2020-03-23 17:41:55] local.DEBUG: debug everyMinute  
[2020-03-23 17:42:55] local.DEBUG: debug everyMinute  
[2020-03-23 17:43:55] local.DEBUG: debug everyMinute  
[2020-03-23 17:44:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:45:55] local.DEBUG: debug everyMinute  
[2020-03-23 17:45:56] local.INFO: info everyFiveMinutes  
[2020-03-23 17:45:57] local.WARNING: warning everyFifteenMinutes  
[2020-03-23 17:46:55] local.DEBUG: debug everyMinute  
[2020-03-23 17:47:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:48:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:49:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:50:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:50:56] local.INFO: info everyFiveMinutes  
[2020-03-23 17:50:57] local.NOTICE: notice everyTenMinutes  
[2020-03-23 17:51:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:52:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:53:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:54:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:55:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:55:57] local.INFO: info everyFiveMinutes  
[2020-03-23 17:56:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:57:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:58:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:59:56] local.DEBUG: debug everyMinute  
[2020-03-23 18:00:56] local.DEBUG: debug everyMinute  
[2020-03-23 18:00:58] local.INFO: info everyFiveMinutes  
[2020-03-23 18:00:59] local.NOTICE: notice everyTenMinutes  
[2020-03-23 18:01:00] local.WARNING: warning everyFifteenMinutes  
[2020-03-23 18:01:01] local.ERROR: error everyThirtyMinutes  
[2020-03-23 18:01:02] local.CRITICAL: critical hourly  
Enter fullscreen mode Exit fullscreen mode

Have fun exploring the scheduler in Laradock!


laravel version used: 6.0 LTS
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
jinseokoh profile image
Chuck JS. Oh

Great articles! Just to be perfectly clear, either crontab setup within workspace or scheduler config in supervisor.d within php-worker is enough. We don't need to have the 2 setups at the same time. To me, having those 2 setups sounds like redundant. Please correct me if I'm wrong.

Collapse
 
dendihandian profile image
Dendi Handian • Edited

Maybe, I haven't figured it out how to make it executes schedule:run and queue:work simultaneously in one worker and worked as we expected.

I just following it from the laradock documentation.