How to stop long running publishes.

A problem that often occurs on Sitecore solutions is the accidental large publish. A user mistakenly selects a top level Sitecore item, checks Sub-items and Related Items and then clicks  publish.

This blocks the publish queue for the next hour as it is completes, delaying other content editors and frustrating everyone.

The only way to recover from this situation is to restart the publishing server. If you have a dedicated publishing server this may not be too much of a problem but it will clear the publish queue. This means that you have to notify all your content editors and ask them to start their publishes again. If you don't have a separate publishing server then you have to sit and wait for the publish to complete or kick off all your users!

However this is a third way to terminate the publish without restarting the server or clearing the publish queue.

Unfortunately there isn't a way to stop a publishing job gracefully once it has started but we can stop it ungracefully. We can do this by creating a processor that throws an error:

    public  class Terminator: Sitecore.Publishing.Pipelines.PublishItem.PublishItemProcessor
    {
        public override void Process(PublishItemContext context)
        {
            PublishJobManager.Instance.CheckTermination();
        } 
    }

The PublishJobManager is an custom class that contains the following code:

    public class PublishJobManager
    {
        private bool _terminateFlag = false;

        public static PublishJobManager Instance { get; set; }
 
        static PublishJobManager()
        { 
            Instance = new PublishJobManager();
        }

        public void CheckTermination()
        {
            if (_terminateFlag)
            {
                _terminateFlag = false;
                throw new PublishTerminatedException("This publish has been terminated. Contact your administrator");
            }
        }

        public void FlagTermination()
        {
         
                _terminateFlag = true;
            
        }

 

 

We can add our Terminator processor to the publishItem pipeline:

 

      <publishItem>
        <!-- should be the last processor-->
        <processor type="Glass.PublishViewer.Pipelines.PublishItem.Terminator, Glass.PublishViewer" />
      </publishItem>

 

With the processor configured now all we need to do is call the PublishingJobManager.Instance.FlagTermination() method when a long publish is executing.

The user who started the publish will see an exception in their Publish Window and their publish job will end. The next publish job will then automatically start.

Although a brutal way to stop a publish it is quick and keeps the Content Editors happy and the CM environment up a running.

If you don't want to have to write this code yourself then checkout the Glass.PublishViewer which has this feature and many more features, like the ability to terminate queued publishes. 

comments powered by Disqus