protected virtual async Task <PipelineContinuation> ExecuteContributor(ICommunicationContext context, ContributorCall call) { using ( PipelineLog.Operation(this, "Executing contributor {0}.{1}".With(call.ContributorTypeName, call.Action.Method.Name))) { PipelineContinuation nextStep; try { nextStep = await call.Action(context); } catch (Exception e) { context.Response.StatusCode = 500; context.ServerErrors.Add(new Error { Title = "Fatal error", Message = "An exception was thrown while processing a pipeline contributor", Exception = e }); nextStep = PipelineContinuation.Abort; } return(nextStep); } }
async Task RenderNow(ICommunicationContext context, PipelineStage stage) { PipelineLog.WriteDebug("Pipeline is in RenderNow mode."); if (!stage.ResumeFrom <KnownStages.IOperationResultInvocation>()) { if (stage.OwnerStage != null) { PipelineLog.WriteError("Trying to launch nested pipeline to render error failed."); AttemptCatastrophicErrorNotification(context); return; } using ( PipelineLog.Operation(this, "Rendering contributor has already been executed. Calling a nested pipeline to render the error.")) { var nestedPipeline = new PipelineStage(this, stage); if (!nestedPipeline.ResumeFrom <KnownStages.IOperationResultInvocation>()) { throw new InvalidOperationException("Could not find an IOperationResultInvocation in the new pipeline."); } await RunCallGraph(context, nestedPipeline); } } }
public void Initialize() { if (IsInitialized) { return; } using (PipelineLog.Operation(this, "Initializing the pipeline.")) { foreach (var item in _resolver.ResolveAll <IPipelineContributor>()) { PipelineLog.WriteDebug("Initialized contributor {0}.", item.GetType().Name); _contributors.Add(item); } _callGraph = GenerateCallGraph(); } IsInitialized = true; PipelineLog.WriteInfo("Pipeline has been successfully initialized."); }
IEnumerable <ContributorCall> GenerateCallGraph() { var bootstrapper = _contributors.OfType <KnownStages.IBegin>().Single(); var tree = new DependencyTree <ContributorNotification>( new ContributorNotification(bootstrapper, new Notification(this, null))); foreach (var contrib in _contributors.Where(x => x != bootstrapper)) { _notificationRegistrations.Clear(); using (PipelineLog.Operation(this, "Initializing contributor {0}.".With(contrib.GetType().Name))) contrib.Initialize(this); foreach (var reg in _notificationRegistrations.DefaultIfEmpty(new Notification(this, null))) { tree.CreateNode(new ContributorNotification(contrib, reg)); } } foreach (var notificationNode in tree.Nodes) { foreach (var parentNode in GetCompatibleTypes(tree, notificationNode, notificationNode.Value.Notification.AfterTypes)) { parentNode.ChildNodes.Add(notificationNode); } foreach (var childNode in GetCompatibleTypes(tree, notificationNode, notificationNode.Value.Notification.BeforeTypes)) { childNode.ParentNodes.Add(notificationNode); } } var graph = tree.GetCallGraph().Select(x => new ContributorCall(x.Value.Contributor, x.Value.Notification.Target, x.Value.Notification.Description)); LogContributorCallChainCreated(graph); return(graph); }