Laravel Workflow 扇出扇入,并发处理pdf的demo
本来想存草稿的,不小心按回车就发布出去了
medium.com/@rlmc/laravel-workflow-...
任务链 是一种工作流设计模式,涉及一系列活动的顺序执行,一个活动的输出有可能成为链中下一个活动的输入。这种模式经常被用来创建一个线性的、按部就班的流程来完成一项任务。
Chaining is a workflow design pattern that involves the sequential execution of a series of activities, with the output of one activity potentially serving as the input to the next activity in the chain. This pattern is often used to create a linear, step-by-step process for completing a task.
chaining
相比之下,扇出/扇入模式涉及到将一个任务划分为更小的子任务,然后将这些子任务的结果结合起来,产生最终结果。这种模式经常被用来并行化一个任务,并通过利用多个队列工作者的力量来提高其性能。
In contrast, the fan-out/fan-in pattern involves dividing a task into smaller sub-tasks and then combining the results of those sub-tasks to produce the final result. This pattern is often used to parallelize a task and improve its performance by leveraging the power of multiple queue workers.
fan-out/fan-in
有两个阶段:扇出和扇入。
There are two phases: fan-out and fan-in.
在扇出阶段,工作流程将主要任务分为较小的子任务,并将每个子任务分配给不同的活动。在扇入阶段,工作流程收集各活动的结果,并将它们结合起来,产生最终结果。
In the fan-out phase, the workflow divides the main task into smaller sub-tasks and assigns each of those sub-tasks to a different activity. In the fan-in phase, the workflow collects the results of the activities and combines them to produce the final result.
This article is part of a series on Larvel Workflow, a durable workflow engine that allows users to write long running persistent distributed workflows (orchestrations) in PHP powered by Laravel Queues. Inspired by Temporal and Azure Durable Functions.
下面的工作流程代表了一个扇出/扇入模式的简单例子,其中多个活动被平行执行,然后它们的结果被合并在一起。
The below workflow represents a simple example of a fan-out/fan-in pattern in which multiple activities are executed in parallel and their results are then merged together.
该工作流程将创建PDF的任务划分为多个活动,每个活动负责渲染文档的一个页面。一旦单个页面被渲染,工作流程的扇入阶段将渲染的页面合并成一个单一的PDF文档。
The workflow divides the task of creating a PDF into activities, with each activity responsible for rendering a single page of the document. Once the individual pages have been rendered, the fan-in phase of the workflow combines the rendered pages into a single PDF document.
<?php
namespace App\Workflows\BuildPDF;
use Workflow\ActivityStub;
use Workflow\Workflow;
class BuildPDFWorkflow extends Workflow
{
public function execute()
{
$page1 = ActivityStub::make(ConvertURLActivity::class, 'https://example.com/');
$page2 = ActivityStub::make(ConvertURLActivity::class, 'https://example.com/');
$pages = yield ActivityStub::all([$page1, $page2]);
$result = yield ActivityStub::make(MergePDFActivity::class, $pages);
return $result;
}
}
并行渲染页面然后合并的工作流
workflow to render pages in parallel and then merge them
The ConvertURLActivity
is passed a URL as an argument, and it converts the contents of that URL into a PDF document. Because two separate activities are created, this results in the execution of two instances of ConvertURLActivity
in parallel.
<?php
namespace App\Workflows\BuildPDF;
use Illuminate\Support\Facades\Http;
use Workflow\Activity;
class ConvertURLActivity extends Activity
{
public function execute($url)
{
$fileName = uniqid() . '.pdf';
Http::withHeaders([
'Apikey' => 'YOUR-API-KEY-GOES-HERE',
])
->withOptions([
'sink' => storage_path($fileName),
])
->post('https://api.cloudmersive.com/convert/web/url/to/pdf', [
'Url' => $url,
]);
return $fileName;
}
}
activity that uses Cloudmersive API to convert URL to PDF
Next, the BuildPDFWorkflow
uses ActivityStub::all
to wait for both ConvertURLActivity
instances to complete. This is an example of the fan-in part of the fan-out/fan-in pattern, as it collects the results of the parallel activities and combines them into a single array of PDF files.
Finally, the BuildPDFWorkflow
executes theMergePDFActivity
, which is passed the array of PDFs that were generated by the ConvertURLActivity
instances, and merges them into a single PDF document.
<?php
namespace App\Workflows\BuildPDF;
use setasign\Fpdi\Fpdi;
use Workflow\Activity;
class MergePDFActivity extends Activity
{
public function execute($pages)
{
$fileName = uniqid() . '.pdf';
$pdf = new Fpdi();
foreach ($pages as $page) {
$pdf->AddPage();
$pdf->setSourceFile(storage_path($page));
$pdf->useTemplate($pdf->importPage(1));
}
$pdf->Output('F', storage_path($fileName));
foreach ($pages as $page) {
unlink(storage_path($page));
}
return $fileName;
}
}
activity to merge all the pages into a single PDF
This is what the final PDF looks like…
both pages have been merged into a single PDF
Overall, using the fan-out/fan-in pattern in this way can significantly reduce the time it takes to create a PDF document, making the process more efficient and scalable.
Thanks for reading!
本作品采用《CC 协议》,转载必须注明作者和本文链接