laravel综合话题:队列——异步消息的分发

laravel综合话题队列——异步消息的定义

由上篇laravel综合话题:队列——异步消息的定义_队列,php_szuaudi的博客-CSDN博客
我们知道,laravel通过调用dispatch方法分发任务,但实际上整个过程只是做异步消息的定义工作。在本篇中,我们探究任务类对象是怎么被持久化的。

任务的分发

一个非常关键的地方是PendingDispatch类。在该类中有一个不能忽略的方法:

	/**
     * Handle the object's destruction.
     *
     * @return void
     */
    public function __destruct()
    {
   
        app(Dispatcher::class)->dispatch($this->job);
    }

PendingDispatch对象销毁时(可能是HTTP请求结束,脚本执行完成),将会执行该段代码,将会把我们定义的任务类对象传递给app(Dispatcher::class)->dispatch方法。我们看一下app(Dispatcher::class)->dispatch($this->job);的内容。

Dispatcher

Illuminate\Contracts\Bus\Dispatcher是一个laravel的Contracts接口,接口的实现类在laravel应用程序启动时创建及绑定。参见laravel中文文档laravel核心架构中的说明:Contracts |《Laravel 5.5 中文文档 5.5》| Laravel China 社区
我们使用php artisan tinker在控制台中打印出Dispatcher绑定的类。
Contracts\Dispatcher
可以发现Dispatcher接口绑定的是Illuminate\Bus\Dispatcher类,我们在Illuminate\Bus\Dispatcher类中查看Dispatcher方法做了什么。

<?php

class Dispatcher implements QueueingDispatcher
{
   
	...
	
	/**
     * Create a new command dispatcher instance.
     *
     * @param  \Illuminate\Contracts\Container\Container  $container
     * @param  \Closure|null  $queueResolver
     * @return void
     */
    public function __construct(Container $container, Closure $queueResolver = null)
    {
   
        $this->container = $container;
        $this->queueResolver = $queueResolver;
        $this->pipeline = new Pipeline($container);
    }
    
	/**
     * Dispatch a command to its appropriate handler.
     *
     * @param  mixed  $command
     * @return mixed
     */
    public function dispatch($command)
    {
   
        if ($this->queueResolver && $this->commandShouldBeQueued($command)) {
   
            return $this->dispatchToQueue($command);
        }

        return $this->dispatchNow($command);
    }

	/**
     * Dispatch a command to its appropriate handler in the current process.
     *
     * @param  mixed  $command
     * @param  mixed  $handler
     * @return mixed
     */
    public function dispatchNow($command, $handler = null)
    {
   
        if ($handler || $handler = $this->getCommandHandler($command)) {
   
            $callback = function ($command) use ($handler) {
   
                return $handler->handle($command);
            };
        } else {
   
            $callback = function ($command) {
   
                return $this->container->call([$command, 'handle']);
            };
        }

        return $this->pipeline->send($command)->through($this->pipes)->then($callback);
    }

	/**
     * Determine if the given command should be queued.
     *
     * @param  mixed  $command
     * @return bool
     */
    protected function commandShouldBeQueued($command)
    {
   
        return $command instanceof ShouldQueue;
    }

	/**
     * Dispatch a command to its appropriate handler behind a queue.
     *
     * @param  mixed  $command
     * @return mixed
     *
     * @throws \RuntimeException
     */
    public function dispatchToQueue($command)
    {
   
        $connection = $command->connection ?? null;

        $queue = call_user_func($this->queueResolver, $connection);

        if (! $queue instanceof Queue) {
   
            throw new RuntimeException('Queue resolver did not return a Queue implementation.');
        }

        if (method_exists($command, 'queue')) {
   
            return $command->queue($queue, $command);
        }

        return $this->pushCommandToQueue($queue, $command);
    }

	/**
     * Push the command onto the given queue instance.
     *
     * @param  \Illuminate\Contracts\Queue\Queue  $queue
     * @param  mixed  $command
     * @return mixed
     */
    protected function pushCommandToQueue($queue, $command)
    {
   
        if (isset($command->queue, $command->delay)) {
   
            return $queue->laterOn($command->queue, $command->delay, $command);
        }

        if (isset($command->queue)) {
   
            return $queue->pushOn($command->queue, $command);
        }

        if (isset($command->delay)) {
   
            return $queue->later($command->delay, $command);
        }

        return $queue->push($command);
    }
}

现在我们梳理一下大概过程:

  1. dispatch方法被调用。如果$this->queueResolver && $this->
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值