In describing the invocation and execution of timer jobs within SharePoint's Timer Service framework, there are a few possible approaches. We could begin by describing the SPJobDefinition class and its various descendants. Another approach would be to describe how the Timer Service instantiates and invokes the jobs. The approach we'll take is to go through many of the standard SharePoint Timer Jobs, using them as examples of types of jobs and paradigms in job creation.
The first two jobs we encounter on our journey are the two internal timer jobs - the Sweep job and the Lock Refresh job. These jobs are not associated with a service instance or Web Application; they are instead automatically added to the local job collection each time the Timer Service is started. The Sweep job checks for other jobs which failed to acquire a lock when they were run and tries again to acquire a lock for them. The Lock Refresh job updates the time for any locks already acquired by this Timer Service Instance (i.e. server). In the ULS logs, the Sweep job is sometimes referred to as "Internal Timer Job 0," and the Lock Refresh job is known as "Internal Timer Job 1." Attached to this post is the sequence of ULS logs typically created by runs of each of these jobs.
In a healthy farm, administrators will likely never need to concern themselves with these jobs. They do however have several important configurable elements which admins should be aware of. These are set on the farm's Timer Service, which can be retrieved as follows:
PS:> $farm = Get-SPFarmPS:> $farm.TimerService
Three configurable properties of the Timer Service are SweepSchedule, RefreshLockSchedule, and LockTimeout. By default, the Sweep job runs once every hour; the RefreshLock job runs every 15 minutes; and the Lock Timeout period is 20 minutes. It seems logical that the RefreshLock job be scheduled at least more frequently than the period of the Lock Timeout so that locks are refreshed before they time out. I cannot state definitively whether performance would be effected negatively by setting the Lock Timeout lower.
The following seven jobs are configured by default when a new farm is created. They can be restored by running the EnsureDefaultJobs() method on the SPTimerService object retrieved above, as follows:
PS:> $farm = Get-SPFarmPS:> $farm.TimerService.EnsureDefaultJobs()
every 15 minutes
daily between 4:31 and 4:33
weekly Sunday 5:00
daily between 0:31 and 0:33
daily between 0:51 and 0:53
daily at 6:00
every 1 minute
We will discuss the Config Refresh job in this article and the other jobs later.
The Config Refresh job will be our first encounter with SPJobDefinition. Properties of instances of SPJobDefinition represent data used by the Timer Service to execute jobs properly. This data includes the Service or Web Application with which the job is associated, the Server on which the job is designated to run (when applicable), the Lock Type of the job (to be discussed later), the job's Title and Description, and finally the job's schedule. The virtual Execute() method is overridden in derived classes to define the actions the job will take; it is this method that is called when the job is invoked.
Every 15 seconds.
The Config Refresh job is one of the most important of the timer jobs. By monitoring version numbers, it detects when changes have been made to objects in SharePoint's shared object store (in the Configuration Database), and updates file and in-memory object caches on the local server accordingly. In addition, it evaluates these changes for any impact they have on locally scheduled jobs and modifies the store of jobs for the local server. For example, if a service instance on a server is brought online through an update, jobs associated with that service will now be scheduled for execution by the local Timer Service Instance.
The Config Refresh Job is one of two jobs in the farm allowed to run more frequently than once a minute; it runs every 15 seconds by default.
In addition to its own work, during the process of running the Config Refresh job, the server checks itself to see if it is busy (based on HTTP Throttling Settings). If it is, all pausable jobs are paused until the next run of the Config Refresh Job (at which point the server checks to see if it is busy again). Results of this check are written to the ULS log as "The current server busy status is (true/false)." If jobs don't seem to be running on a server, this could be something to check.
We will discuss other jobs going forward.