Basics of invoking Sitecore agent programmatically

Howdy my dear readers, I hope you must be doing great!

Yes, I’m back here to write a new blog post after so long time. Sorry for not sharing anything with you since so long. But got busy with lot of bits and pieces. But it’s good to be busy, the busier you are the more you have to share!

So, keep visiting – going to share more with you in upcoming days! [Free advice: You can subscribe to this blog via EMAIL SUBSCRIPTION box given in right side – which means that whenever any new post gets posted here, you will get an email!]

Challenge:

Before few weeks, we wanted to run our agent on specific time. [If you don’t know about Sitecore agents or know little bit. But would like to know more — I would strongly recommend you to read links given in Good to read section at last of this post!]

Now, a question will come in your mind that if you setup frequency to 5 Minutes [00:05:00] then it won’t get executed after every 5 minutes? The answer is yes and no both. Let me take some excerpt from Alex Shyba‘s blog post — http://sitecoreblog.alexshyba.com/2007/02/publish-at-specific-time.html

The nature of the Sitecore scheduled operation is cyclic. The task’s execution time relies on the frequency and interval parameters in the web.config file. This approach has significant benefits. Since there is no way to either prevent the ASP.NET process from recycling or predict the recycle time, the cyclic approach makes it easier to guarantee that your scheduled task will be executed in next timeframe despite ASPNET process terminates the task execution.

Frequency will work in normal conditions. For example if you are running some cleanup in background to clear log file and if it gets executed by 5 minutes delay then it’s not a critical situation. But consider a time critical task your agent is doing in our case it is publishing.  If someone has scheduled for 12:15 and your task’s frequency is 5 Minutes and your task started executing in following manner:

12:03 – First time Agent started

12:08 – Second time Agent started

12:13 – Third time Agent started

12:18 – Fourth time Agent started

12:15 — Scheduled publish should have completed [Just a note : Here, would like to we are using our custom scheduler for publishing and not the Sitecore one. Our scheduler invokes on every time interval and checks publishing details — If found it publishes it!]

In summary:

1. Sitecore scheduler will get executed. But you can’t assure that it will get executed in given time.

2. Also, you can’t predict ASP.NET Recycling. And Sitecore scheduler solely resided on ASP.NET process.

Solution:

So, we took publishing at specific time blog’s instance and implemented our solution in following way:

1. Create a web-service in our Sitecore solution.

2. Within that added one web-method which will invoke  our Sitecore agent, following code shows how you can invoke Sitecore agent programmatically:

foreach (XmlNode node in Factory.GetConfigNodes("scheduling/agent"))
{
try
{
object obj = Factory.CreateObject(node, true);

string name = XmlUtil.GetAttribute("name", node);

if (name == "<YOURAGENTNAMEGOESHERE>")
{
string method = XmlUtil.GetAttribute("method", node);

JobOptions options = new JobOptions(name, "", "", obj, method);
options.AtomicExecution = true;
// TODO : Other properties
JobManager.Start(options);

break;
}
}
catch (Exception ex)
{
// TODO : Log exception and return failure reason

}

Other properties to understand:

AfterLife — deternimes the end date of a job;
InitialDelay — deternimes a delay before starting a job;
AtomicExecution — allows running a job in async way.

3. Create a console application, which will call above create web-service’s web method to invoke Sitecore agent.

4. Create a Windows Scheduled task and scheduled it to run after every 15 Minutes [We kept it 15 Minutes because we wanted it so, you can configure it as per your need]. [Needless to say, if for any reason your Sitecore instance is sleeping, this service will wake it up and then invoke Sitecore agent – So, if your DB is huge and pref-etch cache size is big then please add that time in your agent starting time — Just a worst case scenario!]

5. That’s it!

Few more challenges we faced while doing  these, which would like to share with you:

1.  When one of your agent is executing then it won’t execute another agent. If you check code via reflector then you will find that Sitecore.Tasks.Scheduler loops through all agents and call’s agent’s execute method and if you see implementation of Agent.Execute then it calls JobManager.Start(options).WaitHandle.WaitOne(); — which blocks current thread while each of agents is not executed.

2. TIME BEFORE PUBLISHING STATUS EXPIRES – If your publishing takes more than 2 Hours then your publish might get failed. Because of following configuration entry:

<!--  TIME BEFORE PUBLISHING STATUS EXPIRES
The time before a cached status registration expires.
Default value: 02:00:00
-->
<setting name="Publishing.TimeBeforeStatusExpires" value="02:00:00" />

solution is set it to a biggest number, till which time your publishing can run!

Happy Invoking of Sitecore agent via code! 🙂

PS : Special thanks to Yuriy Bogomolov (Sitecore Support) for providing this suggestion and Yogesh who did all this
investigation and worked on this challenge!

Good to read:

http://sitecorejohn.wordpress.com/2010/04/05/all-about-sitecore-scheduling-agents-and-tasks/

https://sitecorebasics.wordpress.com/2011/04/12/scheduled-task-is-not-getting-executed/

http://sitecoreblog.alexshyba.com/2007/02/publish-at-specific-time.html

http://www.sitecore.net/Community/Technical-Blogs/John-West-Sitecore-Blog/Posts/2012/03/Run-Scheduled-Agents-Interactively-in-the-Sitecore-ASPNET-CMS.aspx

http://sdn.sitecore.net/doc/api%205.0/Sitecore.Jobs.JobOptionsMembers.html

http://briancaos.wordpress.com/2012/02/06/using-sitecore-jobs/