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.

Laravel Workflow: Job Chaining vs. Fan-out/Fan-in
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.

Laravel Workflow: Job Chaining vs. Fan-out/Fan-in
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…

Laravel Workflow: Job Chaining vs. Fan-out/Fan-in
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 协议》,转载必须注明作者和本文链接
CV专员在静静的抄你码
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!