成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

剖析Laravel隊(duì)列系統(tǒng)--推送作業(yè)到隊(duì)列

maochunguang / 2727人閱讀

摘要:有幾種有用的方法可以使用將作業(yè)推送到特定的隊(duì)列在給定的秒數(shù)之后推送作業(yè)延遲后將作業(yè)推送到特定的隊(duì)列推送多個(gè)作業(yè)推送特定隊(duì)列上的多個(gè)作業(yè)調(diào)用這些方法之后,所選擇的隊(duì)列驅(qū)動(dòng)會(huì)將給定的信息存儲(chǔ)在存儲(chǔ)空間中,供按需獲取。

原文鏈接https://divinglaravel.com/queue-system/pushing-jobs-to-queue

There are several ways to push jobs into the queue:
有幾種方法可以將作業(yè)推送到隊(duì)列中:

Queue::push(new InvoiceEmail($order));

Bus::dispatch(new InvoiceEmail($order));

dispatch(new InvoiceEmail($order));

(new InvoiceEmail($order))->dispatch();

As explained in a previous dive, calls on the Queue facade are calls on the queue driver your app uses, calling the push method for example is a call to the push method of the QueueDatabaseQueue class in case you"re using the database queue driver.

There are several useful methods you can use:

調(diào)用Queue facade是對(duì)應(yīng)用程序使用的隊(duì)列驅(qū)動(dòng)的調(diào)用,如果你使用數(shù)據(jù)庫隊(duì)列驅(qū)動(dòng),調(diào)用push方法是調(diào)用QueueDatabaseQueue類的push方法。

有幾種有用的方法可以使用:

// 將作業(yè)推送到特定的隊(duì)列
Queue::pushOn("emails", new InvoiceEmail($order));

// 在給定的秒數(shù)之后推送作業(yè)
Queue::later(60, new InvoiceEmail($order));

// 延遲后將作業(yè)推送到特定的隊(duì)列
Queue::laterOn("emails", 60, new InvoiceEmail($order));

// 推送多個(gè)作業(yè)
Queue::bulk([
    new InvoiceEmail($order),
    new ThankYouEmail($order)
]);

// 推送特定隊(duì)列上的多個(gè)作業(yè)
Queue::bulk([
    new InvoiceEmail($order),
    new ThankYouEmail($order)
], null, "emails");

After calling any of these methods, the selected queue driver will store the given information in a storage space for workers to pick up on demand.

調(diào)用這些方法之后,所選擇的隊(duì)列驅(qū)動(dòng)會(huì)將給定的信息存儲(chǔ)在存儲(chǔ)空間中,供workers按需獲取。

Using the command bus 使用命令總線

Dispatching jobs to queue using the command bus gives you extra control; you can set the selected connection, queue, and delay from within your job class, decide if the command should be queued or run instantly, send the job through a pipeline before running it, actually you can even handle the whole queueing process from within your job class.

The Bus facade proxies to the ContractsBusDispatcher container alias, this alias is resolved into an instance of BusDispatcher inside BusBusServiceProvider:

使用命令總線調(diào)度作業(yè)進(jìn)行排隊(duì)可以給你額外控制權(quán); 您可以從作業(yè)類中設(shè)置選定的connection, queue, and delay 來決定命令是否應(yīng)該排隊(duì)或立即運(yùn)行,在運(yùn)行之前通過管道發(fā)送作業(yè),實(shí)際上你甚至可以從你的作業(yè)類中處理整個(gè)隊(duì)列過程。

Bug facade代理到 ContractsBusDispatcher 容器別名,此別名解析為BusDispatcher內(nèi)的BusBusServiceProvider的一個(gè)實(shí)例:

$this->app->singleton(Dispatcher::class, function ($app) {
    return new Dispatcher($app, function ($connection = null) use ($app) {
        return $app[QueueFactoryContract::class]->connection($connection);
    });
});

所以Bus::dispatch() 調(diào)用的 dispatch() 方法是 BusDispatcher 類的:

public function dispatch($command)
{
    if ($this->queueResolver && $this->commandShouldBeQueued($command)) {
        return $this->dispatchToQueue($command);
    } else {
        return $this->dispatchNow($command);
    }
}

This method decides if the given job should be dispatched to queue or run instantly, the commandShouldBeQueued() method checks if the job class is an instance of ContractsQueueShouldQueue, so using this method your job will only be queued in case you implement the ShouldQueue interface.

We"re not going to look into dispatchNow in this dive, it"ll be discussed in detail when we dive into how workers run jobs. For now let"s look into how the Bus dispatches your job to queue:

該方法決定是否將給定的作業(yè)分派到隊(duì)列或立即運(yùn)行,commandShouldBeQueued() 方法檢查作業(yè)類是否是 ContractsQueueShouldQueue, 的實(shí)例,因此使用此方法,您的作業(yè)只有繼承了ShouldQueue接口才會(huì)被放到隊(duì)列中。

我們不會(huì)在這篇中深入dispatchNow,我們將在深入worker如何執(zhí)行作業(yè)中詳細(xì)討論。 現(xiàn)在我們來看看總線如何調(diào)度你的工作隊(duì)列:

public function dispatchToQueue($command)
{
    $connection = isset($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);
    } else {
        return $this->pushCommandToQueue($queue, $command);
    }
}

First Laravel checks if a connection property is defined in your job class, using the property you can set which connection Laravel should send the queued job to, if no property was defined null will be used and in such case Laravel will use the default connection.

Using the connection value, Laravel uses a queueResolver closure to build the instance of the queue driver that should be used, this closure is set inside BusBusServiceProvider while registering the Dispatcher instance:

首先 Laravel會(huì)檢查您的作業(yè)類中是否定義了connection 屬性,使用這個(gè)屬性可以設(shè)置Laravel應(yīng)該將排隊(duì)作業(yè)發(fā)送到哪個(gè)連接,如果未定義任何屬性,將使用null屬性,在這種情況下Laravel將使用默認(rèn)連接。

通過設(shè)置的連接,Laravel使用一個(gè)queueResolver閉包來構(gòu)建應(yīng)該使用哪個(gè)隊(duì)列驅(qū)動(dòng)的實(shí)例,當(dāng)注冊(cè)調(diào)度器實(shí)例的時(shí)候這個(gè)閉包在BusBusServiceProvider 中被設(shè)置:

function ($connection = null) use ($app) {
    return $app[ContractsQueueFactory::class]->connection($connection);
}

ContractsQueueFactory is an alias for QueueQueueManager, so in other words this closure returns an instance of QueueManager and sets the desired connection for the manager to know which driver to use.

Finally the dispatchToQueue method checks if the job class has a queue method, if that"s the case the dispatcher will just call this method giving you full control over how the job should be queued, you can select the queue, assign delay, set maximum retries, timeout, etc...

In case no queue method was found, a call to pushCommandToQueue() calls the proper pushmethod on the selected queue driver:

ContractsQueueFactoryQueueQueueManager的別名,換句話說,該閉包返回一個(gè)QueueManager實(shí)例,并為manager設(shè)置所使用的隊(duì)列驅(qū)動(dòng)需要的連接。

最后,dispatchToQueue方法檢查作業(yè)類是否具有queue方法,如果調(diào)度器調(diào)用此方法,可以完全控制作業(yè)排隊(duì)的方式,您可以選擇隊(duì)列,分配延遲,設(shè)置最大重試次數(shù), 超時(shí)等

如果沒有找到 queue 方法,對(duì) pushCommandToQueue() 的調(diào)用將調(diào)用所選隊(duì)列驅(qū)動(dòng)上的push方法:

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);
}

The dispatcher checks for queue and delay properties in your Job class & picks the appropriate queue method based on that.

調(diào)度器檢查Job類中的 queuedelay ,并根據(jù)此選擇適當(dāng)?shù)年?duì)列方法。

So I can set the queue, delay, and connection inside the job class? 所以我可以設(shè)置工作類中的隊(duì)列,延遲和連接?

Yes, you can also set a tries and timeout properties and the queue driver will use these values as well, here"s how your job class might look like:

是的,您還可以設(shè)置一個(gè)triestimeout 屬性,隊(duì)列驅(qū)動(dòng)也將使用這些值,以下工作類示例:

class SendInvoiceEmail{
    public $connection = "default";

    public $queue = "emails";

    public $delay = 60;

    public $tries = 3;

    public $timeout = 20;
}
Setting job configuration on the fly 即時(shí)設(shè)置作業(yè)配置

Using the dispatch() global helper you can do something like this:

使用 dispatch() 全局幫助方法,您可以執(zhí)行以下操作:

dispatch(new InvoiceEmail($order))
        ->onConnection("default")
        ->onQueue("emails")
        ->delay(60);

This only works if you use the BusQueueable trait in your job class, this trait contains several methods that you may use to set some properties on the job class before dispatching it, for example:

這只有在您在作業(yè)類中使用 BusQueueable trait時(shí)才有效,此trait包含幾種方法,您可以在分發(fā)作業(yè)類之前在作業(yè)類上設(shè)置一些屬性,例如:

public function onQueue($queue)
{
    $this->queue = $queue;

    return $this;
}
But in your example we call the methods on the return of dispatch()! 但是在你的例子中,我們調(diào)用dispatch()的返回方法!

Here"s the trick:

這是訣竅:

function dispatch($job)
{
    return new PendingDispatch($job);
}

This is the definition of the dispatch() helper in Foundation/helpers.php, it returns an instance of BusPendingDispatch and inside this class we have methods like this:

這是在Foundation/helpers.php中的dispatch()幫助方法的定義,它返回一個(gè)BusPendingDispatch 的實(shí)例,并且在這個(gè)類中,我們有這樣的方法:

public function onQueue($queue)
{
    $this->job->onQueue($queue);

    return $this;
}

So when we do dispatch(new JobClass())->onQueue("default"), the onQueue method of PendingDispatch will call the onQueue method on the job class, as we mentioned earlier job classes need to use the Queueable trait for all this to work.

所以當(dāng)我們執(zhí)行 dispatch(new JobClass())->onQueue("default"), 時(shí),PendingDispatchonQueue 方法將調(diào)用job類上的 onQueue 方法,如前所述,作業(yè)類需要使用所有這些的 Queueable trait來工作。

Then where"s the part where the Dispatcher::dispatch method is called? 那么調(diào)用Dispatcher::dispatch方法的那部分是哪里?

Once you do dispatch(new JobClass())->onQueue("default") you"ll have the job instance ready for dispatching, the actual work happens inside PendingDispatch::__destruct():

一旦你執(zhí)行了 dispatch(new JobClass())->onQueue("default"),你將讓作業(yè)實(shí)例準(zhǔn)備好進(jìn)行調(diào)度,實(shí)際的工作發(fā)生在 PendingDispatch::__destruct()中:

public function __destruct()
{
    app(Dispatcher::class)->dispatch($this->job);
}

This method, when called, will resolve an instance of Dispatcher from the container and call the dispatch() method on it. A __destruct() is a PHP magic method that"s called when all references to the object no longer exist or when the script terminates, and since we don"t store a reference to the PendingDispatch instance anywhere the __destruct method will be called immediately:

調(diào)用此方法時(shí),將從容器中解析 Dispatcher 的一個(gè)實(shí)例,然后調(diào)用它的dispatch()方法。 destruct()是一種PHP魔術(shù)方法,當(dāng)對(duì)對(duì)象的所有引用不再存在或腳本終止時(shí),都會(huì)調(diào)用,因?yàn)槲覀儾粫?huì)立即在 __destruct方法中存儲(chǔ)對(duì)PendingDispatch 實(shí)例的引用,

// Here the destructor will be called rightaway
dispatch(new JobClass())->onQueue("default");

// 如果我們調(diào)用unset($temporaryVariable),那么析構(gòu)函數(shù)將被調(diào)用
// 或腳本完成執(zhí)行時(shí)。
$temporaryVariable = dispatch(new JobClass())->onQueue("default");
Using the Dispatchable trait 使用可調(diào)度的特征

You can use the BusDispatchable trait on your job class to be able to dispatch your jobs like this:

您可以使用工作類上的 BusDispatchable trait來調(diào)度您的工作,如下所示:

(new InvoiceEmail($order))->dispatch();

Here"s how the dispatch method of Dispatchable looks like:

調(diào)度方法 Dispatchable看起來像這樣:

public static function dispatch()
{
    return new PendingDispatch(new static(...func_get_args()));
}

As you can see it uses an instance of PendingDispatch, that means we can do something like:

正如你可以看到它使用一個(gè) PendingDispatch的實(shí)例,這意味著我們可以做一些像這樣的事:

(new InvoiceEmail($order))->dispatch()->onQueue("emails");

轉(zhuǎn)載請(qǐng)注明:?轉(zhuǎn)載自Ryan是菜鳥 | LNMP技術(shù)棧筆記

如果覺得本篇文章對(duì)您十分有益,何不 打賞一下

本文鏈接地址:?剖析Laravel隊(duì)列系統(tǒng)--推送作業(yè)到隊(duì)列

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/23159.html

相關(guān)文章

  • 剖析Laravel隊(duì)列系統(tǒng)--準(zhǔn)備隊(duì)列作業(yè)

    摘要:原文鏈接我們推送到隊(duì)列的每個(gè)作業(yè)都存儲(chǔ)在按執(zhí)行順序排序的某些存儲(chǔ)空間中,該存儲(chǔ)位置可以是數(shù)據(jù)庫,存儲(chǔ)或像這樣的第三方服務(wù)。這個(gè)數(shù)字從開始,在每次運(yùn)行作業(yè)時(shí)不斷增加。 原文鏈接https://divinglaravel.com/queue-system/preparing-jobs-for-queue Every job we push to queue is stored in som...

    marek 評(píng)論0 收藏0
  • 剖析Laravel隊(duì)列系統(tǒng)--Worker

    摘要:一旦這一切完成,方法會(huì)運(yùn)行在類屬性在命令構(gòu)造后設(shè)置容器解析實(shí)例,在中我們?cè)O(shè)置了將使用的緩存驅(qū)動(dòng),我們也根據(jù)命令來決定我們調(diào)用什么方法。作業(yè)只在以上起效在上也無效處理作業(yè)方法調(diào)用觸發(fā)事件觸發(fā)事件。 譯文GitHub https://github.com/yuansir/diving-laravel-zh 原文鏈接https://divinglaravel.com/queue-system...

    CollinPeng 評(píng)論0 收藏0
  • 剖析Laravel隊(duì)列系統(tǒng)--初探

    摘要:配有內(nèi)置的隊(duì)列系統(tǒng),可幫助您在后臺(tái)運(yùn)行任務(wù),并通過簡(jiǎn)單的來配置系統(tǒng)在不同情況下起作用。您可以在中管理隊(duì)列配置,默認(rèn)情況下它有使用不同隊(duì)列驅(qū)動(dòng)的幾個(gè)連接,您可以看到項(xiàng)目中可以有多個(gè)隊(duì)列連接,也可以使用多個(gè)隊(duì)列驅(qū)動(dòng)程序。 原文鏈接https://divinglaravel.com/queue-system/before-the-dive Laravel receives a request...

    pubdreamcc 評(píng)論0 收藏0
  • 剖析 Laravel 計(jì)劃任務(wù)--事件屬性

    摘要:所以在這里創(chuàng)建一個(gè)事件的兩個(gè)實(shí)際方法是通過調(diào)用或,第一個(gè)提交一個(gè)的實(shí)例,后者提交來做一些特殊處理。那么會(huì)用表達(dá)式檢查命令是否到期嗎恰恰相反,使用庫來確定命令是否基于當(dāng)前系統(tǒng)時(shí)間相對(duì)于我們?cè)O(shè)置的時(shí)區(qū)。 譯文GitHub https://github.com/yuansir/diving-laravel-zh 原文鏈接 https://divinglaravel.com/task-sche...

    xiaowugui666 評(píng)論0 收藏0
  • laravel 隊(duì)列

    摘要:如果任務(wù)沒有在規(guī)定時(shí)間內(nèi)完成,那么該有序集合的任務(wù)將會(huì)被重新放入隊(duì)列中。這兩個(gè)進(jìn)程操縱了三個(gè)隊(duì)列,其中一個(gè),負(fù)責(zé)即時(shí)任務(wù),兩個(gè),負(fù)責(zé)延時(shí)任務(wù)與待處理任務(wù)。如果任務(wù)執(zhí)行成功,就會(huì)刪除中的任務(wù),否則會(huì)被重新放入隊(duì)列中。 在實(shí)際的項(xiàng)目開發(fā)中,我們經(jīng)常會(huì)遇到需要輕量級(jí)隊(duì)列的情形,例如發(fā)短信、發(fā)郵件等,這些任務(wù)不足以使用 kafka、RabbitMQ 等重量級(jí)的消息隊(duì)列,但是又的確需要異步、重試...

    BDEEFE 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<