Using Quartz.Net to Schedule Jobs in Windows Azure Worker Roles

January 20, 2013 — 17 Comments

I was looking for a way to create Cron jobs in Worker Roles on Windows Azure and I found Quartz.Net. A Nuget package which is still being maintained as of January 2013. The documentation wasn’t great and was mostly out of date. Furthermore the API seems to have evolved quite a bit over time. The framework seems quite capable and very flexible. I’m barely using any of its potential at the moment! It has schedules and triggers, with a better understanding of its functionality, I would probably grant it more responsibility in my workflow.

The following is an example that demonstrates how I was able to successfully schedule jobs.

Start by implementing the IJob interface to create a job that can be managed by Quartz.Net.

public class DailyJob : IJob { public void Execute(IJobExecutionContext context) { //Do your daily work here } }

Then in the RoleEntryPoint OnStart() method create and configure the scheduler with a trigger and the daily job. This is the part that was greatly lacking in documentation. To get this working I had to poke around the available methods and objects using IntelliSense. Once you have created the scheduler, be sure to keep a reference to it in your Worker Role instance. This will ensure that your jobs execute.

public class WorkerRole : RoleEntryPoint
{
    public override void Run()
    {
        //default project template implementation
        while (true)
        {
            Thread.Sleep(10000);
            Trace.WriteLine("Working", "Information");
        }
    }

    public override bool OnStart()
    {
        ServicePointManager.DefaultConnectionLimit = 12;
        ConfigureScheduler();
        return base.OnStart();
    }

    public override void OnStop()
    {
        sched.Shutdown(false);
        sched = null;
        base.OnStop();
    }

    IScheduler sched;
    private void ConfigureScheduler()
    {
     var schedFact = new StdSchedulerFactory();

     sched = schedFact.GetScheduler();
     var job = new JobDetailImpl("DailyJob", null, typeof(DailyJob));
     var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
     var cronScheduleBuilder = CronScheduleBuilder.DailyAtHourAndMinute(17, 15)
                                                   .InTimeZone(timeZoneInfo);
     var trigger = TriggerBuilder.Create()
                                 .StartNow()
                                 .WithSchedule(cronScheduleBuilder)
                                 .Build();

     sched.ScheduleJob(job, trigger);
     sched.Start();
    }
}

When configuring a time based job, its quite important to keep in mind that all Windows Azure servers utilize UTC time, and ‘en-US’ locale settings. It’s imperative that you make sure that your job is scheduled to execute in the right time zone. Use TimeZoneInfos to get the correct time zone info object.

var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

var cronScheduleBuilder = CronScheduleBuilder.DailyAtHourAndMinute(17, 15)
                                             .InTimeZone(timeZoneInfo);
var trigger = TriggerBuilder.Create()
                            .StartNow()
                            .WithSchedule(cronScheduleBuilder)
                            .Build();

 

Time Zone IDs recognized by .NET

Time Zone ID Time Zone Display Name
Morocco Standard Time (GMT) Casablanca
GMT Standard Time (GMT) Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London
Greenwich Standard Time (GMT) Monrovia, Reykjavik
W. Europe Standard Time (GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna
Central Europe Standard Time (GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague
Romance Standard Time (GMT+01:00) Brussels, Copenhagen, Madrid, Paris
Central European Standard Time (GMT+01:00) Sarajevo, Skopje, Warsaw, Zagreb
W. Central Africa Standard Time (GMT+01:00) West Central Africa
Jordan Standard Time (GMT+02:00) Amman
GTB Standard Time (GMT+02:00) Athens, Bucharest, Istanbul
Middle East Standard Time (GMT+02:00) Beirut
Egypt Standard Time (GMT+02:00) Cairo
South Africa Standard Time (GMT+02:00) Harare, Pretoria
FLE Standard Time (GMT+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius
Israel Standard Time (GMT+02:00) Jerusalem
E. Europe Standard Time (GMT+02:00) Minsk
Namibia Standard Time (GMT+02:00) Windhoek
Arabic Standard Time (GMT+03:00) Baghdad
Arab Standard Time (GMT+03:00) Kuwait, Riyadh
Russian Standard Time (GMT+03:00) Moscow, St. Petersburg, Volgograd
E. Africa Standard Time (GMT+03:00) Nairobi
Georgian Standard Time (GMT+03:00) Tbilisi
Iran Standard Time (GMT+03:30) Tehran
Arabian Standard Time (GMT+04:00) Abu Dhabi, Muscat
Azerbaijan Standard Time (GMT+04:00) Baku
Mauritius Standard Time (GMT+04:00) Port Louis
Caucasus Standard Time (GMT+04:00) Yerevan
Afghanistan Standard Time (GMT+04:30) Kabul
Ekaterinburg Standard Time (GMT+05:00) Ekaterinburg
Pakistan Standard Time (GMT+05:00) Islamabad, Karachi
West Asia Standard Time (GMT+05:00) Tashkent
India Standard Time (GMT+05:30) Chennai, Kolkata, Mumbai, New Delhi
Sri Lanka Standard Time (GMT+05:30) Sri Jayawardenepura
Nepal Standard Time (GMT+05:45) Kathmandu
N. Central Asia Standard Time (GMT+06:00) Almaty, Novosibirsk
Central Asia Standard Time (GMT+06:00) Astana, Dhaka
Myanmar Standard Time (GMT+06:30) Yangon (Rangoon)
SE Asia Standard Time (GMT+07:00) Bangkok, Hanoi, Jakarta
North Asia Standard Time (GMT+07:00) Krasnoyarsk
China Standard Time (GMT+08:00) Beijing, Chongqing, Hong Kong, Urumqi
North Asia East Standard Time (GMT+08:00) Irkutsk, Ulaan Bataar
Singapore Standard Time (GMT+08:00) Kuala Lumpur, Singapore
W. Australia Standard Time (GMT+08:00) Perth
Taipei Standard Time (GMT+08:00) Taipei
Tokyo Standard Time (GMT+09:00) Osaka, Sapporo, Tokyo
Korea Standard Time (GMT+09:00) Seoul
Yakutsk Standard Time (GMT+09:00) Yakutsk
Cen. Australia Standard Time (GMT+09:30) Adelaide
AUS Central Standard Time (GMT+09:30) Darwin
E. Australia Standard Time (GMT+10:00) Brisbane
AUS Eastern Standard Time (GMT+10:00) Canberra, Melbourne, Sydney
West Pacific Standard Time (GMT+10:00) Guam, Port Moresby
Tasmania Standard Time (GMT+10:00) Hobart
Vladivostok Standard Time (GMT+10:00) Vladivostok
Central Pacific Standard Time (GMT+11:00) Magadan, Solomon Is., New Caledonia
New Zealand Standard Time (GMT+12:00) Auckland, Wellington
Fiji Standard Time (GMT+12:00) Fiji, Kamchatka, Marshall Is.
Tonga Standard Time (GMT+13:00) Nuku’alofa
Azores Standard Time (GMT-01:00) Azores
Cape Verde Standard Time (GMT-01:00) Cape Verde Is.
Mid-Atlantic Standard Time (GMT-02:00) Mid-Atlantic
E. South America Standard Time (GMT-03:00) Brasilia
Argentina Standard Time (GMT-03:00) Buenos Aires
SA Eastern Standard Time (GMT-03:00) Georgetown
Greenland Standard Time (GMT-03:00) Greenland
Montevideo Standard Time (GMT-03:00) Montevideo
Newfoundland Standard Time (GMT-03:30) Newfoundland
Atlantic Standard Time (GMT-04:00) Atlantic Time (Canada)
SA Western Standard Time (GMT-04:00) La Paz
Central Brazilian Standard Time (GMT-04:00) Manaus
Pacific SA Standard Time (GMT-04:00) Santiago
Venezuela Standard Time (GMT-04:30) Caracas
SA Pacific Standard Time (GMT-05:00) Bogota, Lima, Quito, Rio Branco
Eastern Standard Time (GMT-05:00) Eastern Time (US & Canada)
US Eastern Standard Time (GMT-05:00) Indiana (East)
Central America Standard Time (GMT-06:00) Central America
Central Standard Time (GMT-06:00) Central Time (US & Canada)
Central Standard Time (Mexico) (GMT-06:00) Guadalajara, Mexico City, Monterrey
Canada Central Standard Time (GMT-06:00) Saskatchewan
US Mountain Standard Time (GMT-07:00) Arizona
Mountain Standard Time (Mexico) (GMT-07:00) Chihuahua, La Paz, Mazatlan
Mountain Standard Time (GMT-07:00) Mountain Time (US & Canada)
Pacific Standard Time (GMT-08:00) Pacific Time (US & Canada)
Pacific Standard Time (Mexico) (GMT-08:00) Tijuana, Baja California
Alaskan Standard Time (GMT-09:00) Alaska
Hawaiian Standard Time (GMT-10:00) Hawaii
Samoa Standard Time (GMT-11:00) Midway Island, Samoa
Dateline Standard Time (GMT-12:00) International Date Line West

 

Summary

Event though Quartz.Net had documentation that wasn’t great and that it was mostly out of date, I recommend taking a closer look. The framework seems quite capable and very flexible. It has schedules, triggers and a few other functionalities, with a better understanding of its functionalities, I would probably grant it more responsibility in my workflow.

17 responses to Using Quartz.Net to Schedule Jobs in Windows Azure Worker Roles

  1. 

    Nice post! Have you thought about using some sort of concurrency check if you have more than 1 worker? Blob lease? Would be interested in your thoughts.

    Like

    • 

      Thanks, actually that was the next step. At the moment, my jobs are hosted on a node that is responsible for persisting data to SQL Database and since it doesn’t require any scaling, I’ve been putting it off for a while. If your architecture is composed of worker roles who are designed to scale out. Blob leases are a great way to go. But I think there may be a need for some kind of strategy when there is a need to distribute tasks or jobs evenly over many Role instances.

      I think this would make for a great blog topic.

      Like

  2. 

    What did you find the CPU utilization was when using Quartz.NET? How much overhead did Quartz.NET take up in monitoring the schedules?

    Like

    • 

      It’s barely noticeble. My Extra Small virtual machine instances on Windows Azure report 0.13% on idle time and i’ve got a few other processes that aren’t in Quartz.Net.

      I also created a scheduler in my personal tools that allows me to configure basic times schedules for daily tasks.
      I will probably post about it soon, the code is available on GitHub, JobSchedule.cs. It allows me to configure the schedules from the Cloud Configuration instead of hard coding it.

      As you can see there is a lot of room for refactoring…

      Like

  3. 

    Hi Alexandre,

    How about when we are using quartz with multiple instances. If one instance that schedules the job goes down, how will the other instances maintain it. Because if one instance goes down then the triggers of that instance also goes down.

    So how to make use of windows azure feature.

    Like

    • 

      Hi Rajat,

      You have found the drawback to this method. I did not come across this issue, because I usually run my tasks twice a day. if the first fails the second will pickup the slack.

      scheduling tasks using any scheduler will probably give you the same problem.

      In this case I would recommend looking into using queues which are able to recover from this type of failure.

      Like

      • 

        Hi Alexandre,

        My question is if the instance that creates the scheduler object goes down or gets deleted will

        the further jobs get scheduled if yes who will handle those jobs.

        Because what I did is:

        1) I have a worker role in windows azure that takes the jobs from the queue that are been put to queue by web role. And i have many instances of the worker role, any instance may pick up the job and schedule it.

        2) Now the problem is: Assume job1 is picked by instance1 and job2 is picked by instance2 and now at some point of time the instance2 gets deleted or goes down. Then the job2 that is assigned to instance2 (job2 scheduled by instance2) how will it continue to schedule the remaining tasks periodically.

        Do we have some facility in quartz so that we can redirect the job to some other instance in the deployment. In other words how we can take the advantage of windows azure cloud.

        Like

        • 

          Hi Jajat,

          You’ve got an excellent challenge there, because you have a few key questions in there.

          First there is a need to figure out if the Worker Role has recycled, or if it was taken down for maintenance. Has the Worker Role failed over? Has the Worker Role been able to execute code when it stopped?

          Then you also need to inspect how you are tracking jobs. I’m not sure if the queue is the best solutions here. It may be part of a greater solution depending on the number of jobs that need to be scheduled for specific times.

          I found this question on stackoverflow about a stateful schedule http://stackoverflow.com/questions/6503780/quartz-net-job-storage-query

          IMO, this is more along the lines of what you need, because when the Role fails over it will read its configuration from the store and rebuild itself. a queue can be used to store jobs before you add them to the stateful schedule.

          On NuGet you also have a project that provides a stateful schedules
          Using MongoDB https://nuget.org/packages/quartz.impl.mongodb/

          You could also implement your own data store using Windows Azure Table Storage to keep a stateful schedule.

          These solutions are simpler than trying to figure out which task has or has not run and detecting if the Worker Role responsible for hosting Quartz is down, recycling or failing over.

          Let me know if this helps
          Alex

          Like

          • 

            Hi Alex,

            That is a great suggestion,

            Sorry for disturbing you with too many questions.

            I have a small doubt about quartz. I am using ADOJob store quartz mechanism. Here since

            the jobs and triggers are stored in database, but there might be something stored on the

            primary memory and flushing of which will result in the loss of scheduler right…?

            Thanks
            -Rajat

            Like

  4. 

    Hi Alex,

    That is a great suggestion,

    Sorry for disturbing you with too many questions.

    I have a small doubt about quartz. I am using ADOJob store quartz mechanism. Here since

    the jobs and triggers are stored in database, but there might be something stored on the

    primary memory and flushing of which will result in the loss of scheduler right…?

    Thanks
    -Rajat

    Like

    • 

      Hi Rajat,

      Forgive me for the delay, I recently started a new mandate and I haven’t been around as much as I would have liked.

      I must admit that I am not very familiar with the inner workings of ADOjob store for Quartz. I have seen people talk about a data store using Table Storage but I haven’t been able to find it. I was hoping to have time to implement one this week but time simply wasn’t there..

      As for your question, my personal hunch is that yes, there is always a possibility of losing some state when a server goes down. But hopefully it should not be significant.

      To validate this, some tests should be done, any results would be very interesting.

      I recommend visiting https://github.com/quartznet/quartznet/issues and ask them directly.

      Like

  5. 

    Have you tried to use exporter service of quartz ?? I am trying to use quartz with worker role multiinstace.
    But i want connect to exporter service to get all jobs etc..

    Like

Trackbacks and Pingbacks:

  1. Dealing With Worker Role Failovers by Scheduling Duplicate Jobs | Alexandre Brisebois - August 21, 2013

    […] This question came from Rajat on a post I did about using using Quartz.Net to schedule jobs in Windows Azure Worker roles. […]

    Like

  2. The Top 10 Most-Read #WindowsAzure Posts of 2013 | Alexandre Brisebois - December 29, 2013

    […] Using Quartz.Net to Schedule Jobs in Windows Azure Worker Roles – 3,284 reads […]

    Like

  3. Windows Azure : Créer simplement un scheduler | Soat blog - February 4, 2014

    […] Si vous voulez plus d’informations sur Quart.net, Alexandre Brisebois a écrit un super article sur le sujet que je vous conseille de […]

    Like

  4. Provisioning Virtual Machine in Azure - June 6, 2014

    […] Quartz.net (http://www.quartz-scheduler.net/), una libreria che permette, con pochi semplici passi (http://alexandrebrisebois.wordpress.com/2013/01/20/using-quartz-net-to-schedule-jobs-in-windows-azur…), la creazione di uno scheduler che esegue una classe che contiene le procedure da eseguire […]

    Like

  5. Softjam Innovation Blog - June 6, 2014

    […] Quartz.net (http://www.quartz-scheduler.net/), una libreria che permette, con pochi semplici passi (http://alexandrebrisebois.wordpress.com/2013/01/20/using-quartz-net-to-schedule-jobs-in-windows-azur…), la creazione di uno scheduler che esegue una classe che contiene le procedure da eseguire […]

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s