Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Artisan::call('horizon:terminate') The command "horizon:terminate" does not exist. #28217

Closed
shadoWalker89 opened this issue Apr 14, 2019 · 11 comments

Comments

@shadoWalker89
Copy link
Contributor

  • Laravel Version: 5.8.11
  • PHP Version: 7.2.14

Description:

Calling this from my application will cause this error

        Artisan::call('horizon:terminate');

Symfony \ Component \ Console \ Exception \ CommandNotFoundException
The command "horizon:terminate" does not exist.

When i call the command from the command line it works.

If you ask why i'm calling the horizon:terminate from my application, well i have a settings module that allows users to update the application configuration by updating the .env file.

After doing so,
I want to do two things

        Artisan::call('config:cache');
        Artisan::call('horizon:terminate');

The config:cache works but the horizon:terminate does not.

@driesvints
Copy link
Member

You need to have Horizon installed for this. This is the issue tracker for the Laravel framework, not Horizon.

@shadoWalker89
Copy link
Contributor Author

@driesvints That is the problem, Horizon is already installed and it says command not found

@driesvints
Copy link
Member

Can you first please try one of the following support channels? If you can actually identify this as a bug, feel free to report back and I'll gladly help you out.

Thanks!

@brunogaspar
Copy link
Contributor

@shadoWalker89 Not sure where you're calling that Artisan command, but you can only call that through the "terminal".

Hope this https://github.com/laravel/horizon/blob/3.0/src/HorizonServiceProvider.php#L168 helps to understand the cause perhaps?

@shadoWalker89
Copy link
Contributor Author

@brunogaspar Thanks, that explains why i'm getting command not found.

For now what i'm doing

exec('cd '.base_path().' && /usr/local/bin/ea-php72 artisan horizon:terminate');

@shadoWalker89
Copy link
Contributor Author

@brunogaspar About why i'm calling that command, like i said in the issue message, the administrator of the application can change configurations saved within the .env file. I need to terminate horizon so it can pickup the new config values

@brunogaspar
Copy link
Contributor

Yup, figured much.

Your solution is not bad, although not super Laravel Clean :)

@nonoesp
Copy link

nonoesp commented Jun 2, 2020

Ran into the same issue (with another package).

It seems only commands registered outside of the if ($this->app->runningInConsole()) call are available to be called from within the app's runtime with Artisan:call.

Made a little write up explaining my solution.

In my case, I'm the maintainer of the package and could easily work around the limitation by taking the command I want to use in Laravel out of the if statement.

But I just tested that you can register the horizon:terminate command yourself in your app's $commands array in app/Console/Kernel.php.

For instance, I did this.

protected $commands = [
    \Nonoesp\Folio\Commands\CreateUserCommand::class,
];

While the CreateUserCommand is only registered to the console by the package, I can explicitly make it available for my entire application calling it with Artisan::call('folio:user {email} {password}') (which is this command's signature).

@Helle1
Copy link

Helle1 commented Jan 14, 2021

Ran into the same issue (with another package).

It seems only commands registered outside of the if ($this->app->runningInConsole()) call are available to be called from within the app's runtime with Artisan:call.

Made a little write up explaining my solution.

In my case, I'm the maintainer of the package and could easily work around the limitation by taking the command I want to use in Laravel out of the if statement.

But I just tested that you can register the horizon:terminate command yourself in your app's $commands array in app/Console/Kernel.php.

For instance, I did this.

protected $commands = [
    \Nonoesp\Folio\Commands\CreateUserCommand::class,
];

While the CreateUserCommand is only registered to the console by the package, I can explicitly make it available for my entire application calling it with Artisan::call('folio:user {email} {password}') (which is this command's signature).

I tried that out ... after some research in the laravel files I tried to set the commands up via the AppServiceProvider as the solution with the Kernel.php did not change anything:

public function register()
    {
        //
        $this->commands([
            \Laravel\Horizon\Console\StatusCommand::class,
            \Laravel\Horizon\Console\TerminateCommand::class,
            \Laravel\Horizon\Console\ContinueCommand::class,
            \Laravel\Horizon\Console\HorizonCommand::class
        ]);
    }

But now I am running into new issues (i.e. horizoncommand: Call to undefined function Laravel\Horizon\Console\pcntl_async_signals()) . It seems, that horizon simply is not callable via Aritsan::call() or did I miss something?
Maybe because of Laravel 7 ?

@junaid-A-khan
Copy link

Ran into the same issue (with another package).
It seems only commands registered outside of the if ($this->app->runningInConsole()) call are available to be called from within the app's runtime with Artisan:call.
Made a little write up explaining my solution.
In my case, I'm the maintainer of the package and could easily work around the limitation by taking the command I want to use in Laravel out of the if statement.
But I just tested that you can register the horizon:terminate command yourself in your app's $commands array in app/Console/Kernel.php.
For instance, I did this.

protected $commands = [
    \Nonoesp\Folio\Commands\CreateUserCommand::class,
];

While the CreateUserCommand is only registered to the console by the package, I can explicitly make it available for my entire application calling it with Artisan::call('folio:user {email} {password}') (which is this command's signature).

I tried that out ... after some research in the laravel files I tried to set the commands up via the AppServiceProvider as the solution with the Kernel.php did not change anything:

public function register()
    {
        //
        $this->commands([
            \Laravel\Horizon\Console\StatusCommand::class,
            \Laravel\Horizon\Console\TerminateCommand::class,
            \Laravel\Horizon\Console\ContinueCommand::class,
            \Laravel\Horizon\Console\HorizonCommand::class
        ]);
    }

But now I am running into new issues (i.e. horizoncommand: Call to undefined function Laravel\Horizon\Console\pcntl_async_signals()) . It seems, that horizon simply is not callable via Aritsan::call() or did I miss something? Maybe because of Laravel 7 ?

Just did this as you suggested and the terminate command works for me. All the multiple horizon instances are terminated instantly on my local machine. Still have to test on the server.

 /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        TerminateCommand::class,
    ];

I am on Laravel 8 so may be that's why it worked for me without any error.
Thank You.

@MohamedLamineAllal
Copy link

Laravel 10

<?php

namespace App\Console;

use Laravel\Horizon\Console\TerminateCommand;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
	/**
	 * Register the commands for the application.
	 */
	protected function commands(): void
	{
		$this->load(__DIR__ . '/Commands');
		$this->registerCommand(new TerminateCommand());

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

Works perfect!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants