locked
SPFirstAvailableServiceJobDefinition - How does it work? RRS feed

  • Question

  • So I've been reading more about the new timer jobs that are available for SharePoint 2010.  I'm continually impressed at the added features MS decided to include in this version.  I've created custom timer jobs in the past and now I'd like to create another custom timer job using the SPFirstAvailableServiceJobDefinition class.

    Based on the documentation I've read, this class runs the job on the first available server which has a specific SPService installed. 

    So my question, what logic is used to determine the "first available server"?   I assume it's based on load balancing and round robin checks to see if servers are up or down, which is not exactly what I'm looking for (but I'll take what I can get). 

    I'm hoping it's based on distributing timer jobs evenly across the farm instead of just creating them all on 1 server until it has to failover.   For example, if I have 3 application servers, all with a specific SPService installed, then what actually occurs when I create 3 new timer jobs from the SPFirstAvailableServiceJobDefinition class?


    http://donahoo-development.com
    • Moved by Anjali Ch -MSFT Saturday, May 14, 2011 1:09 AM (From:SharePoint 2010 - Setup, Upgrade, Administration and Operation)
    Friday, May 6, 2011 7:47 PM

Answers

  • Hi Mike,

    I hope that I can provide a bit more clarification on how the timer jobs are created/executed which may help resolve some of the questions you have asked.

    First of all, we need to distinguish the difference between timer job definition and timer job instance.  When you have created a timer job definition, it does not actually do anything until it is scheduled to run and the timer job service picks it up from the queue and started timer job instance to execute the code in the timer job definition.

    In the case of SPFirstAvailableServiceJobDefinition, it will be deployed to the farm (all APS will have the code base by default) with a timer job schedule specified.  What this means is an entry in the SharePoint database will be created to state when this job needs to be executed.  The timer job service on all the APS will check for any jobs that needs to be executed at the relatively the same time with slight difference like 1/4 sec or something depends on if the APS was busy on another code, etc...  So when there are 5 jobs (one of them created with SPFirstAvailableServiceJobDefinition) that needs to be executed and the timer job service checks for it, the first APS to check into the database will pick up all 5 jobs (assuming the first APS to respond has the associated service running - this is specific to SPFirstAvailableServiceJobDefinition) and execute them asynchronously where as the APS that responded just a split second after will likely find nothing to work on.  At this point, you may be thinking that you are over-loading one APS and leave the others doing nothing.  However, one thing to note is if the first APS picked up 5 jobs, it will not be checking for more timer jobs in the DB that needs to be executed until all 5 jobs are completed.  During that time, the remaining APS will continue to check for timer jobs that needs to be executed.  This is also why we recommend users to stagger their timer job schedules so that not all the jobs are picked up by the same APS.

    Based on the above, I hope it also provided you with some answers to creating/running the same timer jobs on multiple servers at the same time.  The bottom line here is the timer job definition should always be deployed to all APS.  The actual timer job instance is only created when the timer job has reached its designated time of execution.  And when a timer job is flagged as executing pending, all APS has equal chance to pick up the job as long as:

    - it is not still executing the earlier batch of timer jobs it picked up

    - it has the required SPService deployed (for the case of SPFirstAvailableServiceJobDefinition)

    - the timer job is not specifically registered to run on another APS in the farm

    Above is not a complete story of how SharePoint timer jobs are scheduled/executed, but it does provide a glimpse to how the process works and I hope that will help with the questions you have posted above.

    All in all, SharePoint does a pretty good job load balancing the timer jobs that needs to be executed if you just leave SharePoint to handle it.  The only exeception is if you have a lot of custom timer jobs that are registered to run on specific servers in the farm or if only small number of APS in the farm has a very active SPService needed for Service-bound jobs.  In that situations, some actions may be taken to help balance out the work load.

    Cheers,

    Jeff - MSFT

    • Proposed as answer by daniel.larson Thursday, June 30, 2011 10:47 PM
    • Marked as answer by Mike Donahoo Monday, July 18, 2011 5:37 PM
    Tuesday, June 28, 2011 5:55 PM

All replies

  • Hi Mike,

    A job will be provisioned to all application servers. If the job is SPFirstAvailableServiceJobDefinition, the job will be run on the first available server(the server that gets the job at first).

    It is based on the load balancing.
    In my opinion, we are unable to control which server will be the first available server(A little similar with Network Load Balance).

    Thanks,
    Jinchun Chen


    Jin Chen - MSFT
    Thursday, May 12, 2011 10:38 AM
  • So you said that it'll be provisioned on all application servers.  Is this different than what the documentation states?
    "An abstract base class for a timer job that will be run on the first available server where the specified service is provisioned."

    I assumed "first available" really just meant the first server that responds, again like round robin load balancing.  If this is the case, what about a situation where I have two application servers in my farm, both running the specified service.  If I create an SPFirstAvailableServiceJobDefinition timer job, won't it just always be executed on only one of the two servers (at least until that server goes down or becomes unavailable either through failure or network connection loss)?

    So if I really wanted to distribute job execution evenly amongst application servers, I'd have to write that logic myself when I actually create and execute the timer job?

     


    http://donahoo-development.com
    Thursday, May 12, 2011 1:24 PM
  • I've actually been able to reflect the timer job classes and I've found out something interesting....

    The SPFirstAvailableServiceJobDefinition doesn't have any extra code that really distinguishes it from the normal SPTimerJobDefinition class.  In fact, it's really just an abstracted way to create a new SPTimerJobDefinition instance.

    It's basically a normal pausable timer job that has a predefined SPJobLockType of "Job".  There's nothing else really special about it that I can see.
    http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spjoblocktype.aspx

    Since it's automatically specifying the SPJobLockType, then I assume it will always run 1 instance of the job on only 1 server in the farm at any given time.  This probably means that I can't create two SPFirstAvailableServiceJobDefinition based jobs and assume that they'll run in tandem on different servers because of the job lock.

    So my question, it is possible to create and run the same timer job on specific servers at the same time?  This would help to achieve desired functionality of having multiple job instances being evenly distributed among different servers.   Does this make any sense?

     

     


    http://donahoo-development.com
    Thursday, May 12, 2011 2:52 PM
  • Hi Mike,

    I hope that I can provide a bit more clarification on how the timer jobs are created/executed which may help resolve some of the questions you have asked.

    First of all, we need to distinguish the difference between timer job definition and timer job instance.  When you have created a timer job definition, it does not actually do anything until it is scheduled to run and the timer job service picks it up from the queue and started timer job instance to execute the code in the timer job definition.

    In the case of SPFirstAvailableServiceJobDefinition, it will be deployed to the farm (all APS will have the code base by default) with a timer job schedule specified.  What this means is an entry in the SharePoint database will be created to state when this job needs to be executed.  The timer job service on all the APS will check for any jobs that needs to be executed at the relatively the same time with slight difference like 1/4 sec or something depends on if the APS was busy on another code, etc...  So when there are 5 jobs (one of them created with SPFirstAvailableServiceJobDefinition) that needs to be executed and the timer job service checks for it, the first APS to check into the database will pick up all 5 jobs (assuming the first APS to respond has the associated service running - this is specific to SPFirstAvailableServiceJobDefinition) and execute them asynchronously where as the APS that responded just a split second after will likely find nothing to work on.  At this point, you may be thinking that you are over-loading one APS and leave the others doing nothing.  However, one thing to note is if the first APS picked up 5 jobs, it will not be checking for more timer jobs in the DB that needs to be executed until all 5 jobs are completed.  During that time, the remaining APS will continue to check for timer jobs that needs to be executed.  This is also why we recommend users to stagger their timer job schedules so that not all the jobs are picked up by the same APS.

    Based on the above, I hope it also provided you with some answers to creating/running the same timer jobs on multiple servers at the same time.  The bottom line here is the timer job definition should always be deployed to all APS.  The actual timer job instance is only created when the timer job has reached its designated time of execution.  And when a timer job is flagged as executing pending, all APS has equal chance to pick up the job as long as:

    - it is not still executing the earlier batch of timer jobs it picked up

    - it has the required SPService deployed (for the case of SPFirstAvailableServiceJobDefinition)

    - the timer job is not specifically registered to run on another APS in the farm

    Above is not a complete story of how SharePoint timer jobs are scheduled/executed, but it does provide a glimpse to how the process works and I hope that will help with the questions you have posted above.

    All in all, SharePoint does a pretty good job load balancing the timer jobs that needs to be executed if you just leave SharePoint to handle it.  The only exeception is if you have a lot of custom timer jobs that are registered to run on specific servers in the farm or if only small number of APS in the farm has a very active SPService needed for Service-bound jobs.  In that situations, some actions may be taken to help balance out the work load.

    Cheers,

    Jeff - MSFT

    • Proposed as answer by daniel.larson Thursday, June 30, 2011 10:47 PM
    • Marked as answer by Mike Donahoo Monday, July 18, 2011 5:37 PM
    Tuesday, June 28, 2011 5:55 PM
  • Thank you for the very detailed reply.  This is great information.

    If I understand you correctly, I can basically stagger my timer jobs so that they get picked up by different APS.  Therefore, if I have two APS, with only one of them running the required SPService (SPFirstAvailableServiceJobDefinition), and I provision a timer job to execute soon, then only one of the APS will pick it up to execute it.  If both the APS had the required SPService, then the timer job would be picked up by which ever APS queried the database first. 

    What happens if I provision 3 long-running (3+ hr) SPFirstAvailableServiceJobDefinition timer jobs at staggering times of execution (5 PM, 6 PM, 7 PM) using 2 APS that both have the required SPService? 

    Thank you for helping to answer my questions. 


    http://donahoo-development.com
    Thursday, June 30, 2011 5:03 PM
  • Hey Mike

    You can create your own SPService implementation (also implement IServiceAdministration) and attach your job to THAT, so you can specify which servers in the farm can run your job. Don't know if you knew that or not... then you can use that when you provision your job. Here's some sample code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.SharePoint.Administration;
    using Microsoft.SharePoint;
    using System.Runtime.InteropServices;
    
    namespace ApplicationServices
    {
    	[Guid("242E94C9-92CF-423b-B84D-42C704444CB1")]
    	public class FooService : SPService, IServiceAdministration
      {
        public FooService() { }
    		public FooService(string name, SPFarm farm)
          : base(name, farm) {
    				base.Status = SPObjectStatus.Online;
    		}
    
    		public override string TypeName
    		{
    			get
    			{
    				return "foo Service";
    			}
    		}
    
    		internal static string DefaultName = "fooservice";
    
    		public static FooService GetServiceIfProvisioned()
    		{
    			return SPFarm.Local.Services.GetValue<FooService>(DefaultName);
    		}
    		public static FooService Ensure()
    		{
    			SPFarm local = SPFarm.Local;
    			FooService service = local.Services.GetValue<FooService>(DefaultName);
    			if (service == null)
    			{
    				service = new FooService(DefaultName, local);
    				service.Update();
    			}
    			return service;
    		}
    
    		public SPServiceApplication CreateApplication(string name, Type serviceApplicationType, SPServiceProvisioningContext provisioningContext)
    		{
    			throw new NotImplementedException();
    		}
    
    		public SPServiceApplicationProxy CreateProxy(string name, SPServiceApplication serviceApplication, SPServiceProvisioningContext provisioningContext)
    		{
    			throw new NotImplementedException();
    		}
    
    		public SPPersistedTypeDescription GetApplicationTypeDescription(Type serviceApplicationType)
    		{
    			return new SPPersistedTypeDescription("Foo Service", 
    				"My Sample Foo Service.");
    		}
    
    		public Type[] GetApplicationTypes()
    		{
    			return new Type[] { };
    		}
    	}
    }
    
    


    Daniel Larson SharePoint Architect at NewsGator Technologies, Author for Microsoft Press, Father of VI and Eli
    Thursday, June 30, 2011 8:04 PM
  • Thanks Daniel! 

    I've wrote several custom service applications.  One of them implements claims based authorization so that content can be secured by claims in a hierarchical fashion.  Basically, it almost like site groups, but you can nest them and break inheritance if needed.  Another one helps me implement a COMET (reverse AJAX push) methodology so that list or web events can be logged and monitored real time. I use this one in conjunction with HighCharts (javascript library for charting).  The last service application I'm currently writing is an alerting engine that leverages timer jobs and communicates to Lync using UCMA 3.0 in order to send out voice or text messages to mobile devices. All of these implement an SPDatabase, which has very little documentation by the way.

    My question revolves around that last service application and my use of timer jobs.  A job's execution consists of communicating with Lync and performing the necessary alerting functions (email, phone, etc) and then logging them.  A job is executed when an alert (my application's terminology) is activated.  There can be more than 1 alert active at a time.  Therefore, I'd like to execute the timer job in a load balance manner and I needed more information about the types of definitions and how they affect load and performance.

    I hope I'm explaining this effectively.


    http://donahoo-development.com
    Thursday, June 30, 2011 8:26 PM
  • Makes sense! Yeah, I know I was a LITTLE off question, but thought I'd chime in on how you can control what app server you run on, instead of running on all app servers. :)

    What you've done sounds impressive, ping me if you want a job @ newsgator! :)


    Daniel Larson SharePoint Architect at NewsGator Technologies, Author for Microsoft Press, Father of VI and Eli
    Thursday, June 30, 2011 10:43 PM