public override void OnPull() { var source = _stage._sourceFactory(); var subSink = new SubSinkInlet <TOut>(this, "LazySource"); subSink.Pull(); SetHandler(_stage.Out, () => subSink.Pull(), () => { subSink.Cancel(); CompleteStage(); }); subSink.SetHandler(new LambdaInHandler(() => Push(_stage.Out, subSink.Grab()))); try { var value = SubFusingMaterializer.Materialize(source.ToMaterialized(subSink.Sink, Keep.Left), _inheritedAttributes); _completion.SetResult(value); } catch (Exception e) { subSink.Cancel(); FailStage(e); _completion.TrySetException(e); } }
private void RemoveSource(SubSinkInlet <T> src) { var pullSuppressed = ActiveSources == _stage._breadth; _sources.Remove(src); if (pullSuppressed) { TryPull(_stage._in); } if (ActiveSources == 0 && IsClosed(_stage._in)) { CompleteStage(); } }
protected SubSinkInlet <TOut> CreateSubInlet(Outlet <TOut> outlet) { var sinkIn = new SubSinkInlet <TOut>(this, $"RestartWithBackoff{_name}.subIn"); sinkIn.SetHandler(new LambdaInHandler( onPush: () => Push(Out, sinkIn.Grab()), onUpstreamFinish: () => { if (_finishing || MaxRestartsReached() || _onlyOnFailures) { Complete(Out); } else { ScheduleRestartTimer(); } }, /* * upstream in this context is the wrapped stage */ onUpstreamFailure: ex => { if (_finishing || MaxRestartsReached()) { Fail(Out, ex); } else { Log.Warning(ex, "Restarting graph due to failure."); ScheduleRestartTimer(); } })); SetHandler(Out, onPull: () => sinkIn.Pull(), onDownstreamFinish: () => { _finishing = true; sinkIn.Cancel(); }); return(sinkIn); }
protected SubSinkInlet <T> CreateSubInlet <T>(Outlet <T> outlet) { var sinkIn = new SubSinkInlet <T>(this, $"RestartWithBackoff{_name}.subIn"); sinkIn.SetHandler(new LambdaInHandler( onPush: () => { Push(Out, sinkIn.Grab()); }, onUpstreamFinish: () => { if (_finishing) { Complete(Out); } else { Log.Debug("Graph out finished"); OnCompleteOrFailure(); } }, onUpstreamFailure: ex => { if (_finishing) { Fail(_shape.Outlets.First(), ex); } else { Log.Error(ex, "Restarting graph due to failure"); OnCompleteOrFailure(); } })); SetHandler(Out, onPull: () => sinkIn.Pull(), onDownstreamFinish: () => { _finishing = true; sinkIn.Cancel(); }); return(sinkIn); }
public Logic(TaskFlattenSource <T, M> stage, TaskCompletionSource <M> materialized) : base(stage.Shape) { _stage = stage; _materialized = materialized; _sinkIn = new SubSinkInlet <T>(this, "TaskFlattenSource.in"); // initial handler (until task completes) SetHandler(stage.Outlet, new LambdaOutHandler( onPull: () => { }, onDownstreamFinish: () => { if (!_materialized.Task.IsCompleted) { // we used to try to materialize the "inner" source here just to get // the materialized value, but that is not safe and may cause the graph shell // to leak/stay alive after the stage completes _materialized.TrySetException(new StreamDetachedException("Stream cancelled before Source Task completed")); } OnDownstreamFinish(); })); }