dev-master
9999999-devPipeline implementation
MIT
The Development Requires
1.0.0
1.0.0.0Pipeline implementation
MIT
The Development Requires
Pipeline implementation
This package provides a pipeline pattern implementation., (*1)
The pipeline pattern allows you to easily compose sequential stages by chaining stages., (*2)
In this particular implementation the interface consists of two parts:, (*3)
A pipeline consists of zero, one, or multiple stages. A Processor can process a payload against a pipeline. During the processing the payload will be passed to the first stage. From that moment on the resulting value is passed on from stage to stage., (*4)
In the simplest form, the execution chain can be represented as a foreach:, (*5)
$result = $payload; foreach ($stages as $stage) { $result = $stage($result); } return $result;
Effectively this is the same as:, (*6)
$result = $stage3($stage2($stage1($payload)));
Pipelines are implemented as immutable stage chains. When you pipe a new stage, a new pipeline will be created with the added stage. This makes pipelines easy to reuse, and minimizes side-effects., (*7)
Operations in a pipeline, stages, can be anything that satisfies the callable
type-hint, as well as Stage or Pipeline interfaces. So closures and
anything that's invokable is okay., (*8)
$pipeline = (new Pipeline\Simple)->pipe(function ($payload) { return $payload * 10; });
Class based stages are also possible. The Stage can be implemented which
ensures you have the correct method signature for the process
method., (*9)
use SyberIsle\Pipeline\Pipeline; use SyberIsle\Pipeline\Processor; use SyberIsle\Pipeline\Stage; class TimesTwoStage implements Stage { public function process($payload) { return $payload * 2; } } class AddOneStage implements Stage { public function process($payload) { return $payload + 1; } } $pipeline = (new Pipeline\Simple) ->pipe(new TimesTwoStage) ->pipe(new AddOneStage); // Returns 21 (new Processor\FingersCrossed())->process($pipeline, 10);
Because the PipelineInterface is an extension of the StageInterface pipelines can be re-used as stages. This creates a highly composable model to create complex execution patterns while keeping the cognitive load low., (*10)
For example, if we'd want to compose a pipeline to process API calls, we'd create something along these lines:, (*11)
$processApiRequest = (new Pipeline) ->pipe(new ExecuteHttpRequest) // 2 ->pipe(new ParseJsonResponse); // 3 $pipeline = (new Pipeline) ->pipe(new ConvertToPsr7Request) // 1 ->pipe($processApiRequest) // (2,3) ->pipe(new ConvertToResponseDto); // 4 (new Processor\FingersCrossed())->process($pipeline, new DeleteBlogPost($postId));
Because pipelines themselves are immutable, pipeline builders are introduced to facilitate distributed composition of a pipeline., (*12)
The pipeline builders collect stages and allow you to create a pipeline at any given time., (*13)
use SyberIsle\Pipeline\Pipeline\SimpleBuilder; // Prepare the builder $pipelineBuilder = (new SimpleBuilder) ->add(new LogicalStage) ->add(new AnotherStage) ->add(new LastStage); // Build the pipeline $pipeline = $pipelineBuilder->build();
This package is completely transparent when dealing with exceptions. In no case will this package catch an exception or silence an error. Exceptions should be dealt with on a per-case basis. Either inside a stage or at the time the pipeline processes a payload., (*14)
$pipeline = (new Pipeline)->pipe(function () { throw new LogicException(); }); try { (new Processor\FingersCrossed())->process($pipeline, $payload); } catch(LogicException $e) { // Handle the exception. }
The MIT License (MIT). Please see License File for more information., (*15)
Pipeline implementation
MIT
Pipeline implementation
MIT