Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Fork-Join #38

Closed
juzerali opened this issue Jan 9, 2018 · 2 comments
Closed

[Feature Request] Fork-Join #38

juzerali opened this issue Jan 9, 2018 · 2 comments

Comments

@juzerali
Copy link

juzerali commented Jan 9, 2018

Sometimes based on some condition, a pipeline needs to be forked, meaning there is a need to follow one of several disparate paths which have nothing in common. Optionally, later the disjoint paths may join again.

$pipeline = (new Pipeline)
    ->pipe(new TimeTwoStage)
    ->pipe(new AddOneStage)
    ->fork(function($payload) {
            if($payload == 0) return "zero";
            if($payload < 0) return "-";
            if($payload > 0) return "+";
            return false; // for short-circuit
        })
        ->disjoin("zero", $zeroProcessingPipeline)
        ->disjoin("-", $negativeNumberProcessingPipeline)
        ->disjoin("+", $positiveNumberProcessingPipeline)
        ->join()
    ->pipe(new DivideByFiveStage);
@juzerali juzerali changed the title [Feature Request] Join/Disjoin [Feature Request] Fork-Join Jan 9, 2018
juzerali pushed a commit to juzerali/pipeline that referenced this issue Jan 9, 2018
@juzerali
Copy link
Author

juzerali commented Jan 9, 2018

Also it will be better if the fluent API to build the pipeline is shifted to the builder. As per Single Responsibility Principle, responsibility to build an object with complex graph should be outside the object itself, i.e. in a builder.

So building the pipeline will look like this:

$pipeline = (new PipelineBuilder)
    ->pipe(new TimeTwoStage)
    ->fork(function($payload) {
            if($payload < 0) return "-";
            if($payload >= 0) return "+";
        })
        ->disjoin("-", $negativeNumberProcessingPipeline)
        ->disjoin("+", $positiveNumberOrZeroProcessingPipeline)
        ->join()
    ->pipe(new DivideByFiveStage)
    ->build();

juzerali pushed a commit to juzerali/pipeline that referenced this issue Jan 9, 2018
juzerali pushed a commit to juzerali/pipeline that referenced this issue Jan 9, 2018
juzerali pushed a commit to juzerali/pipeline that referenced this issue Jan 9, 2018
juzerali pushed a commit to juzerali/pipeline that referenced this issue Jan 9, 2018
@shadowhand
Copy link
Member

shadowhand commented Jun 8, 2018

I think this would be better solved by using something like php-fp-either, where every stage returns a Right or Left:

use PhpFp\Either\Either;

$pipeline = new Pipeline();
$pipeline = $pipeline->pipe(function (Either $a) {
    return $a->chain(function ($x) {
        return $x * 2;
    };
});

$output = $pipeline->process(Either::of(2))->either(
    function ($left) {
        return 'failed';
    },
    function ($right) {
        return $right;
    }
);

assert($output === 4);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants