标签归档:命令

Laravel 把命令推入队列

如果一个命令需要执行很长时间才会退出,那么把这个命令推入队列就很有必要。Laravel提供了方法:

Artisan::queue('email:send', [
    'user' => 1, '--qn' => 'default'
]);

这里的意思就是由Worker去执行email:send命令,参数就是后面给出的数组。

不过这里需要整明白的是,它推入了队列,但是队列名称是什么,不能指定吗? 第二,Worker取回这个Job时,如果知道它是一个命令,然后执行?

首先,Atisan这个Facade对应一个实现了Illuminate\Contracts\Console\Kernel接口的实例,实现这个接口的类是Illuminate\Foundation\Console\Kernel,我们最终使用的App\Console\Kernel就是从这里继承类继承而来。换句话说,Atisan这个Facade直接对应了App\Console\Kernel实例,它是一个命令管理工具,提供了调用命令的方法。

所以,需要去到Illuminate\Foundation\Console\Kernel中查看具体实现:

    public function call($command, array $parameters = [])
    {
        $this->bootstrap();

        return $this->getArtisan()->call($command, $parameters);
    }

    /**
     * Queue the given console command.
     *
     * @param  string  $command
     * @param  array   $parameters
     * @return void
     */
    public function queue($command, array $parameters = [])
    {
        $this->app['Illuminate\Contracts\Queue\Queue']->push(
            'Illuminate\Foundation\Console\QueuedJob', func_get_args()
        );
    }

看到Kernel的call实际是Artisan应用的call方法的包装器。主要看下queue方法,它从容器中取回队列对象,压了一个Illuminate\Foundation\Console\QueuedJob类型的对象进入队列,push方法第三参数指定队列,这里没有指定,意思就是说它直接放入默认名称(default)的队列。对于一个Job,最终fire方法会被调用,查看Illuminate\Foundation\Console\QueuedJob:

    public function fire($job, $data)
    {
        call_user_func_array([$this->kernel, 'call'], $data);

        $job->delete();
    }

可以看到,直接调用Kernel的call方法。