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); } } }
protected virtual void FinishPipeline(ICommunicationContext context) { context.Request.Entity?.Dispose(); context.Response.Entity?.Dispose(); PipelineLog.WriteInfo("Pipeline finished."); }
bool CanBeExecuted(ContributorCall call) { if (call.Action == null) { PipelineLog.WriteWarning("Contributor call for {0} had a null Action.", call.ContributorTypeName); return(false); } return(true); }
void LogContributorCallChainCreated(IEnumerable <ContributorCall> callGraph) { PipelineLog.WriteInfo("Contributor call chain has been processed and results in the following pipeline:"); int pos = 0; foreach (var contributor in callGraph) { PipelineLog.WriteInfo("{0} {1}", pos++, contributor.ContributorTypeName); } }
public IPipelineExecutionOrder Notify(Func <ICommunicationContext, PipelineContinuation> action) { if (IsInitialized) { PipelineLog.WriteWarning("A pipeline registration through Notify() has been done after the pipeline was initialized. Ignoring."); return(new Notification(this, action)); } var notification = new Notification(this, action); _notificationRegistrations.Add(notification); return(notification); }
protected virtual void AbortPipeline(ICommunicationContext context) { PipelineLog.WriteError("Aborting the pipeline and rendering the errors."); context.OperationResult = new OperationResult.InternalServerError { Title = "The request could not be processed because of a fatal error. See log below.", ResponseResource = context.ServerErrors }; context.PipelineData.ResponseCodec = null; context.Response.Entity.Instance = context.ServerErrors; context.Response.Entity.Codec = null; context.Response.Entity.ContentLength = null; Log.WriteError("An error has occurred and the processing of the request has stopped.\r\n{0}", context.ServerErrors.Aggregate(string.Empty, (str, error) => str + "\r\n" + error.ToString())); }
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); }
protected virtual void FinishPipeline(ICommunicationContext context) { PipelineLog.WriteInfo("Pipeline finished."); }