Invoke Sitecore Scheduling Agent Programmatically

Sitecore provides facility to run scheduled jobs at specified regular interval like DatabaseAgent, UrlAgent, etc. We created our own agent to make scheduled publishing. So, this agent is executed every one hour and starts pending publishing, which can take several minutes say 20-30 minutes.

This can be achieved by creating a scheduling agent in web.config as below:
    <agent name="ScheduledPublish" type="SitecoreTactics.Tasks.StartPublish" method="StartPublish" interval="01:00:00" />
Here, every 1 hour, Sitecore invokes the agent named ScheduledPublish and executes StartPublish method of SitecoreTactics.Tasks.PublishManager class.

Requirement to invoke Sitecore Agent

Now, we had a requirement to invoke our custom agent in between through a Web Page when user wants to do instant publish instead of waiting for next turn of its execution. Should we call our code from the web page itself or invoke the Agent directly programmatically? There was no clear idea which can be a better approach? Below are two approaches we worked on.

Wrong approach we chose earlier to execute code directly

Earlier, we called the PublishManager's StartPublish method directly from the web page, when user clicks on a button as below.
protected void btnStartPublish_Click(object sender, EventArgs e)
{
    SitecoreTactics.Tasks.PublishManager publisher = new SitecoreTactics.Tasks.PublishManager();
    publisher.StartPublish();
}
The limitation in the approach was, the code was executed by the thread of web page or a web request, which needed to be executed more than 30 minutes. But, after the Server's Script timeout (default 5 minutes), the execution was stopped every time and could not complete full job of 30+ minutes. But if same code was executed as a Sitecore Agent, it finished all execution, because Sitecore Agents are executed by separate ManagedThreadPools, which never has TimeOut until they finish job or Application ends.

Correct approach to invoke Sitecore Scheduling Agent

We searched a lot on Google about invoking Sitecore Agent. Later on, Reflector came to our help. Using it we found the code from where Sitecore invokes its agents and we implemented the same code as below:
protected void btnStartPublish_Click(object sender, EventArgs e)
{
 foreach (XmlNode node in Factory.GetConfigNodes("scheduling/agent"))
 {
  object obj = Factory.CreateObject(node, true);
  string name = XmlUtil.GetAttribute("name", node);
 
  if (name == "ScheduledPublish") // Scheduling Agent Name
  {
   string method = XmlUtil.GetAttribute("method", node);
 
   JobOptions options = new JobOptions(name, "", "", obj, method);
   options.AtomicExecution = true; // Allow multiple instances of the agent running simultaneously
   JobManager.Start(options);
 
   break;
  }
 }
}
Now, we are not worried for executing agents's code. Agent's process needs to be executed for one hour, two hours, ten hours? No worries, we can now call Sitecore Jobs programmatically!!

Comments