예제 #1
0
 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);
     }
 }
예제 #2
0
        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);
                }
            }
        }
예제 #3
0
        protected virtual void FinishPipeline(ICommunicationContext context)
        {
            context.Request.Entity?.Dispose();

            context.Response.Entity?.Dispose();

            PipelineLog.WriteInfo("Pipeline finished.");
        }
예제 #4
0
 bool CanBeExecuted(ContributorCall call)
 {
     if (call.Action == null)
     {
         PipelineLog.WriteWarning("Contributor call for {0} had a null Action.", call.ContributorTypeName);
         return(false);
     }
     return(true);
 }
예제 #5
0
        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);
            }
        }
예제 #6
0
        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);
        }
예제 #7
0
        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()));
        }
예제 #8
0
 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.");
 }
예제 #9
0
        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);
        }
예제 #10
0
 protected virtual void FinishPipeline(ICommunicationContext context)
 {
     PipelineLog.WriteInfo("Pipeline finished.");
 }