private void HandOver(SubstreamHandler handler) { if (IsClosed(_stage._out)) { CompleteStage(); } else { _substreamSource = new SubSourceOutlet <T>(this, "SplitSource"); _substreamSource.SetHandler(handler); _substreamCancelled = false; SetHandler(_stage._in, handler); SetKeepGoing(handler.HasInitialElement); if (IsAvailable(_stage._out)) { Push(_stage._out, Source.FromGraph(_substreamSource.Source)); ScheduleOnce(SubscriptionTimer, _timeout); _substreamPushed = true; } else { _substreamPushed = false; } } }
public override void OnPush() { var elem = _logic.Grab(_logic._stage._in); try { if (_logic._stage._predicate(elem)) { var handler = new SubstreamHandler(_logic); CloseThis(handler, elem); _logic.HandOver(handler); } else { // Drain into the void if (_logic._substreamCancelled) { _logic.Pull(_logic._stage._in); } else { _logic._substreamSource.Push(elem); } } } catch (Exception ex) { OnUpstreamFailure(ex); } }
public void OnPush() { var handler = new SubstreamHandler(this); var elem = Grab(_stage._in); if (_stage._decision == Split.SplitDecision.SplitAfter && _stage._predicate(elem)) { Push(_stage._out, Source.Single(elem)); } // Next pull will come from the next substream that we will open else { handler.FirstElement = elem; } HandOver(handler); }
public Logic(Split <T> stage) : base(stage.Shape) { _stage = stage; SetHandler(stage._out, onPull: () => { if (_substreamSource == null) { Pull(stage._in); } else if (!_substreamPushed) { Push(stage._out, Source.FromGraph(_substreamSource.Source)); ScheduleOnce(SubscriptionTimer, _timeout); _substreamPushed = true; } }, onDownstreamFinish: () => { // If the substream is already cancelled or it has not been handed out, we can go away if (!_substreamPushed || _substreamCancelled) { CompleteStage(); } }); // initial input handler SetHandler(stage._in, onPush: () => { var handler = new SubstreamHandler(this); var elem = Grab(_stage._in); if (_stage._decision == Split.SplitDecision.SplitAfter && _stage._predicate(elem)) { Push(_stage._out, Source.Single(elem)); } // Next pull will come from the next substream that we will open else { handler.FirstElement = elem; } HandOver(handler); }, onUpstreamFinish: CompleteStage); }
private void CloseThis(SubstreamHandler handler, T currentElem) { var decision = _logic._stage._decision; if (decision == Split.SplitDecision.SplitAfter) { if (!_logic._substreamCancelled) { _logic._substreamSource.Push(currentElem); _logic._substreamSource.Complete(); } } else if (decision == Split.SplitDecision.SplitBefore) { handler.FirstElement = currentElem; if (!_logic._substreamCancelled) { _logic._substreamSource.Complete(); } } }