ms1987's avatar

Calling Artisan::call('schedule:run') from a controller

Dear All,

I have created a console command that (for now) just outputs a log statement.

That command is scheduled every minute.

I have a controller endpoint (located at /scheduler/run) that performs an Artisan::call(); to the artisan schedule:run command.

Locally it works perfectly (laravel valet & nginx), on production (apache) however, nothing happens when hitting that endpoint... I do get the reply from my controller, but the scheduler is never triggered.

What is even more remarkable is that Artisan::call('my:ping') in my controller directly DOES work.

So it must have something to do with the scheduler...

My route:

Route::get('/scheduler/run', SchedulerController::class)->name('scheduler');

My controller:

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Artisan;

class SchedulerController extends Controller
{
    public function __invoke()
    {
        Artisan::call('schedule:run');

        return response()->noContent();
    }
}

My Kernel.php

<?php

namespace App\Console;

use App\Console\Commands\PingCommand;
use App\Console\Commands\RefreshTwikeyKey;
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 = [
        PingCommand::class,
    ];

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

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

        require base_path('routes/console.php');
    }
}
0 likes
7 replies
bugsysha's avatar

Can you explain why would you do something like that cause I never needed it?

ms1987's avatar

This app is running in a shared hosting environment that does not allow me to create crontabs from cli. They only offer a cron UI that 'calls' an http endpoint on a schedule to take care of cron.

bugsysha's avatar

I think that would not work since you will probably hit timeout limit for php execution. You better spend few more dollars and get yourself a VPS. I know that OVH was super cheap. I've used it long time ago. It was at first $0.99/month then they've increased it to $1.99/month. Never had issues with it.

ms1987's avatar

hehe thanks. this i am aware of, this hosting is what the client has available in this case. So the hosting i cannot change.

Nonetheless, i would love to understand what might be going on here. As i see no timeouts, no errors, ... Also, the scheduler only has the ping command in it, which completes in a few ms, since it only writes a log entry...

bugsysha's avatar

It is probably calling some php function or terminal command which is blacklisted on all shared hosting servers.

Snapey's avatar

better just to perform the command's function in the controller and cut out two middlemen

ms1987's avatar

Upon request they have added a crontab for me on the server directly. That works perfectly.

The mystery remains on why it did not work on the controller approach...

Please or to participate in this conversation.