Musielak Marek

Posted on Monday, November 30, 2009 by Marek Musielak

Custom scheduled jobs in EPiServer - advanced tips

If you are here, you probably know what EPiServer scheduled jobs are. If not, I suggest you to take a look at Ted Nyberg post here Ted Nyberg: scheduled jobs in EPiServer first. If you're still with me, I assume you already have basic knowledge about scheduled jobs in EPiServer.

In this post I want to talk about several things you should take into account during your work with EPiServer scheduled jobs like:
* running the scheduled job on the chosen server
* executing only one EpiServer job in the same time
* executing scheduled job as a specified user
* process within the job thread is executed



Many servers - one job only

If you have many web servers connected to the single DB server (no matter if this is your development or production environment), you should be aware of the fact, that if the job is started automatically ANY of the servers can start your scheduled job. What is more, you can not be sure that the job won't be run on many servers in the same time. In some cases this is desired behavior, while in other it can cause serious problems.

Lets consider a situation when the role of the scheduled job is to perform some CPU consuming calculations. Assume that we have 4 server: 3 of them can be accessed via Internet and the other one is used only for entering content. In this scenario I would like all those calculations to be performed on the 4th server so the users accessing the site do not encounter any performance issues.

There is simple solution - stop EPiServer Scheduler service on the servers that can be accessed via Internet and leave the service running only on the 4th server. Do not forget to set Startup Type of the service to "Manual", in other case the scheduler will start on the machine after the reboot.

Only one job executed in the same time

There are plenty of situations when we don't want to let 2 same scheduled jobs to be executed simultaneously. But when we have a scheduled job that is run very often and execution of which can take a lot of time, we can be pretty sure that such a moment will occur when scheduler will try to execute the same job despite the fact that one job is still running.

To avoid it, we can use System.Threading.Monitor class like this:

using System;

namespace Maras.ScheduledJobs
{
[EPiServer.PlugIn.ScheduledPlugIn(DisplayName = "My job",
Description = "Only one 'My job' will be executed parallelly")]
public class MyJob
{
private static readonly object MyJobLock = new object();

public static string Execute()
{
if (!System.Threading.Monitor.TryEnter(MyJobLock))
{
// other job uses the monitor
return "Job is still running";
}

try
{
// ... here comes the real code of the job
return String.Empty;
}
catch (Exception exc)
{
return string.Format("Unknown exception caught ({0} {1})",
new object[] { exc.Message, exc.StackTrace });
}
finally
{
System.Threading.Monitor.Exit(MyJobLock);
}
}
}
}

It is very important to exit the monitor in finally statement. In other case you can block your jobs until the application is restarted.

Executing EPiServer scheduled job as a specified user

If you execute your job manually from the admin mode, your job is executed with all privileges that your user has. However, when your job is run by the scheduler, it does not have you user access rights. Believe me, it's really easy to forget about it while developing new scheduled job.

Fortunately it's really easy to log with the specified user name in the EPiServer. the only thing to do is to assign new principals to the PrincipalInfo.CurrentPrincipal like this:

EPiServer.Security.PrincipalInfo.CurrentPrincipal =
EPiServer.Security.PrincipalInfo.CreatePrincipal("username");

For more information take a look at Ted Nyberg: Run a scheduled job as a specific EPiServer user.

Process within the job thread is executed

In the development phase of the scheduled job, most of the time you will start your job manually from the admin mode. In this case the job will be run within the web application process and its thread will have all privileges and rights that your user has.

However, when you set the scheduler to run the job automatically, there is a huge difference. Probably the most important is that you don't have user rights, but I already wrote about it above. The other thing that you should consider is that you don't have access to the HttpContext.Current stuff. And probably there are dozens of other things specific for your application.

Summarizing

While developing your custom scheduled job for EPiServer one has to remember that there is a big difference between jobs run manually and jobs run automatically by the scheduler. I hope that after reading this post you won't have any problems with your own scheduled jobs.

If you know about anything else that should be added to the list above, do not hesitate to comment below.

Read More »

Related Posts:


7 Responses to Custom scheduled jobs in EPiServer - advanced tips

  1. Johan Olofsson
    December 2, 2009 at 8:44 AM
    Great post!!

    One comment though: the scheduled job _is_ executed _within_ the web application process when executed automatically (you use the same DataFactory with the same cache for example)!.

    As you points out there is however no HttpContext available (HttpContext.Current is null) and no CurrentUser.

    HttpRuntime should be fine to use though.

    /johan
  2. Marek Musielak
    December 2, 2009 at 3:40 PM
    Thanks Johan, you're right. Already corrected the post.
  3. Bertil
    December 16, 2009 at 9:52 AM
    In a 4.50 environment with 3 servers is it safe to stop EPiServer Scheduler service on 2 servers? What about local cache update that seems to be dependent on the EPiServer Scheduler service?

    Maybe not a problem but I want to make sure no unexpected problems pop up if the service is stopped on two of the servers.

    I need to make sure that a scheduled job is run on the one server inside the firewall.
  4. Marek Musielak
    December 16, 2009 at 10:27 AM
    Thanks for your comment Bertil.

    I have never worked with EPiServer 4.50. But I had 5 servers working on EPiServer 4.61 and scheduler service was running on one of them only. And we had no problems with cache there.
  5. Bertil
    December 17, 2009 at 10:37 AM
    Just ran across this web.config setting.



    Haven't tried it yet but it looks like a solution too.
  6. Bertil
    December 17, 2009 at 10:39 AM
    EPfDisableScheduler
  7. nitin
    September 5, 2010 at 12:14 PM
    What if i want that if 1 server is not able to run the job then 2 server should run it.
    How can i set this setting

Post a Comment