teewurst/pipeline
Composer 安装命令:
composer require teewurst/pipeline
包简介
Recursive Pipeline Construct
README 文档
README
With this lib, we are able to separate long executions into multiple tasks. A pipeline enables you to better fulfill single responsibility requirements. This results in better maintainability and testability.
How to
- The Pipeline passes the Payload and its self into the task.
public function __invoke(PayloadInterface $payload, PipelineInterface $pipeline): PayloadInterface;
- The first task calls the next task, calls the next task, calls the next task ...
$payloadAfterAllSteps = $pipeline->handle($payload);
- Like in PSR-7 (the request object) you are now able to handle all information by adding and getting information from a payload object
$value = $genericPayload->getValue();
$value++;
$genericPayload->setValue($value);
Step-by-Step
- Create Task(s)
- Initialize Pipeline
- Fill Payload
- Execute Pipe
- Evaluate Pipe
Use Pipeline Service
You are able to simple create your pipelines from your DI (PSR-11 Container Service Manager required). It just takes two lines of code (+Config)
The PipelineService class allows you to pass tasks as service hashes.
// .. In your factory $tasksFromEnvConfig = $config->getTasks() // somewhere in your config: [Task1::class, Task2::class, Task3::class]; $pipeline = (new PipelineService)->createPsr11($serviceManager, $tasksFromEnvConfig);
With teewurst/Pipeline you are able to create quite complex tasks in no time:
// Configuration of BiPRO Request (= German XML Request Standard) $tasklist = [ CheckServiceAvailabilityTask::class, [ // do Request ErrorHandlerTask::class, // catch execution of submission even on error [ PrepareDataTask::class, ValidateDataTask::class, DoGetOfferRequestTask::class ], // .. some additional things like set quote, upload documents etc. ], [ // do something additionally LogResultLocalyTask::class, LogResultInDWTask::class, ] ];
Best Practices
- Use
RecursivePipelineto create "Sub Pipelines" => Dynamic Tasks - Because of the Structure every task has a "before handle next step" and "after handle next step"
- Interrupt pipeline by throwing an exception or return $payload without handling the next step
Examples
Initialize Pipeline manually
Of course it would be better to use DI instead of new all the time
// Create Tasks in order of execution $tasks = [ new ExceptionTask(), new ErrorBagTask(), new OpenStreamTask(), new ReadValuesTask(), new ValidateValuesTask(), new RequireDocumentsTask(), new HandleImportTask(), ]; // Create Pipeline $pipeline = new \teewurst\Pipeline\Pipeline($tasks); // Create Payload $payload = new ImportPayload(); // Setup Payload $payload->setEnvironment($env); // <= here you also could use $pipeline->setOptions(...) $payload->setConfig($config); // Do the thing the pipeline is constructed for $payload = $pipeline->handle($payload); // Evaluate result $payload->getMessage();
Simple Task which does something
Use the pipeline object to pass configuration and handle data between tasks
public function __invoke(PayloadInterface $payload, PipelineInterface $pipeline): PayloadInterface { // there is something, so we need to continue with our tasks if ($payload->getValue() > 0) { return $pipeline->handle($payload); } // we do not allow negative values => Completely interrupt process if ($payload->getValue() < 0) { throw new \Exception("Negative Values are not allowed here"); } // Value is 0, let's pretend there is nothing more to do. => Interrupt from here and go back up the callstack return $payload; }
Exception Handling Task
Handle (maybe only certain) exceptions within the pipe
public function __invoke(PayloadInterface $payload, PipelineInterface $pipeline): PayloadInterface { try { // handle next steps BEFORE doing something $payload = $pipeline->handle($payload); } catch (\Throwable $e) { $this->logger->logException($e, ['context' => $payload]); } return $payload; }
Error Bag
Process multiple errors with error bags
public function __invoke(PayloadInterface $payload, PipelineInterface $pipeline): PayloadInterface { // Do something before handle next steps $payload->setErrorBag($this->errorBag); // Pipeline will add errors to error bag $payload = $pipeline->handle($payload); // "On the way back" and after handling, we check if something is inside the error bag if ($payload->getErrorBag()->hasErrors()) { $payload->setMessage($payload->getErrorBag()->toString()); } return $payload; }
teewurst/pipeline 适用场景与选型建议
teewurst/pipeline 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 8.29k 次下载、GitHub Stars 达 3, 最近一次更新时间为 2020 年 01 月 14 日, 在 PHP 生态内属于活跃度较高的组件。
我们在过去多个企业项目中使用过 teewurst/pipeline 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 teewurst/pipeline 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
统计信息
- 总下载量: 8.29k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 3
- 点击次数: 7
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2020-01-14