2

I have setup multitenancy in my laravel project. I use laravel 7.x.

Now, I want to make task scheduler for some commands and that commands need to run for all tenants.

I have two schedule command called in app\Console\Kernel.php.

<?php

namespace App\Console;

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

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

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('cmd:fingerprint')->runInBackground()->everyFiveMinutes()->appendOutputTo(storage_path().'/logs/cron_result.log');
        $schedule->command('cmd:late_early_deduction')->runInBackground()->everyFiveMinutes()->appendOutputTo(storage_path().'/logs/cron_result.log');
    }

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

        require base_path('routes/console.php');
    }
}

Following is the command file of cmd:fingerprint.

<?php

namespace App\Console\Commands;

use App\Models\Tenant;
use Illuminate\Console\Command;
use App\Cron\FingerPrintAttendance;
use Carbon\Carbon;

class FingerPrintAttendance extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'cmd:fingerprint {tenant?}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Fingerprint Attendance';

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

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        if ($this->argument('tenant')) {
            $this->addFingerPrintDataIntoTables(
                Tenant::find($this->argument('tenant'))
            );

        } else {
            Tenant::all()->each(
                function($tenant){
                    return $this->addFingerPrintDataIntoTables($tenant);
                }
            );
        }
    }

    public function addFingerPrintDataIntoTables($tenant)
    {
        $tenant->configure()->use();
        $this->line('==================');
        $this->line("Running Tenant #{$tenant->id} ({$tenant->customer_name}) cmd:fingerprint at " . Carbon::now());
        $fingerPrintAttendance = new FingerPrintAttendance;
        $fingerPrintAttendance->create($tenant);
        $this->line("Ending Tenant #{$tenant->id} ({$tenant->customer_name}) cmd:fingerprint at " . Carbon::now());
    }
}

Here is cmd:late_early_deduction command file.

<?php

namespace App\Console\Commands;

use App\Models\Tenant;
use Illuminate\Console\Command;
use App\Cron\AttendLateEarlyDeduction;
use Carbon\Carbon;

class AttendanceLateEarlyDeduction extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'cmd:late_early_deduction {tenant?}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Attend Late Early Deduction';

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

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {

       if ($this->argument('tenant')) {
            $this->lateEarlyDeduction(
                Tenant::find($this->argument('tenant'))
            );

        } else {
            Tenant::all()->each(
                function($tenant){
                    return $this->lateEarlyDeduction($tenant);
                }
            );
        }

    }

    public function lateEarlyDeduction($tenant)
    {
        $tenant->configure()->use();
        $this->line('==================');        
        $this->line("Running Tenant #{$tenant->id} ({$tenant->customer_name}) cmd:late_early_deduction at " . Carbon::now());
        $AutoRenewLeave = new AttendLateEarlyDeduction;
        $AutoRenewLeave->create($tenant);
        $this->line("Ending Tenant #{$tenant->id} ({$tenant->customer_name}) cmd:late_early_deduction at " . Carbon::now());
    }
}

Then I set task scheduler on my windows 10. My development environment is windows10.

When the task is trigger, it is only run first command and the second command never run. Following is the log result.

==================
Running Tenant #1 (Test A Company) cmd:fingerprint at 2021-12-06 15:50:01
Ending Tenant #1 (Test A Company) cmd:fingerprint at 2021-12-06 15:50:01
==================
Running Tenant #2 (Test B Company) cmd:fingerprint at 2021-12-06 15:50:01
Ending Tenant #2 (Test B Company) cmd:fingerprint at 2021-12-06 15:50:01
==================
Running Tenant #3 (Test C Company) cmd:fingerprint at 2021-12-06 15:50:01
Ending Tenant #3 (Test C Company) cmd:fingerprint at 2021-12-06 15:50:01
==================
Running Tenant #1 (Test A Company) cmd:fingerprint at 2021-12-06 15:55:01
Ending Tenant #1 (Test A Company) cmd:fingerprint at 2021-12-06 15:55:01
==================
Running Tenant #2 (Test B Company) cmd:fingerprint at 2021-12-06 15:55:01
Ending Tenant #2 (Test B Company) cmd:fingerprint at 2021-12-06 15:55:01
==================
Running Tenant #3 (Test C Company) cmd:fingerprint at 2021-12-06 15:55:01
Ending Tenant #3 (Test C Company) cmd:fingerprint at 2021-12-06 15:55:01

But, when I remove runInBackground() from both command, it is run both command. In the laravel doc, it is said, when I use runInBackground(), all commands will run simultaneously. But, it is not working in my code.

The reason I want to run all commands simultaneously because, I have a lot of tenants and I don't want to wait command for each tenants.

My question is, I don't clearly understand why runInBackground() in my code doesn't work ? Is there any alternative way to run all commands without waiting for each tenants.

Cloud
  • 1,004
  • 1
  • 18
  • 47

0 Answers0