Framework: Each artisan command executes App\Console\Kernel schedule() method

Created on 19 Mar 2016  路  6Comments  路  Source: laravel/framework

Laravel 5.2.23
Main issue is that each artisan command executes AppConsoleKernel schedule() method.

On my AppConsoleKernel schedule() method I have next code:

<?php
    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule $schedule
     *
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $user = User::find(1);

        if (!empty($user)) {
            $schedule->call(function () use ($user) {
                $user->changePassword();
            })->cron($user->getCron());
        }
    }

Problems:
For example, I need to deploy my project from scratch - I can't do this because when I execute

php artisan migrate

I get an error: ""Table 'users' doesn't exists"". So at present I should comment out body of method shedule(), run migrations, then uncomment body of shedule() method.

Suggestions?
Thanks.

Most helpful comment

Yes, I may, but I'm not sure that this is necessary to execute schedule() method each time, eg. when we just type

php artisan key:generate

or something else. Why Laravel executes shedule() ? What purpose of this call?
Probably would be better to avoid unnecessary calls on the core of framework.

All 6 comments

Maybe you should do:

if(Schema::hasTable('users')){
    // Code here
}

Yes, I may, but I'm not sure that this is necessary to execute schedule() method each time, eg. when we just type

php artisan key:generate

or something else. Why Laravel executes shedule() ? What purpose of this call?
Probably would be better to avoid unnecessary calls on the core of framework.

schedule() should contain only command registrations, so you should refactor your code so that it queries DB in task itself instead of scheduler registration, and doesn't dynamically set cron with this $user->getCron().

Though, you made a point that Kernel::schedule() shouldn't be run for each and every command.

Same issue here! Any Solutions?

@adarshsojitra as it doesn't appear there will be a change to the framework itself, there are two solutions presented above:

1) Refactor your code so that you abstract anything that is querying the db directly in your schedule() method

2) Wrap your code in a conditional that checks if the table exists before running the code so:

if(Schema::hasTable('users')) {
    $user = User::find(1);
    $schedule->command('user:stats '.$user->id)->dailyAt('23:00');
}

As there have been some comments supporting it, I think #12803 should be reconsidered. (maybe with a better implementation, if someone could figure it out)

Was this page helpful?
0 / 5 - 0 ratings