Blaise Swanwick
Blaise Swanwick

Reputation: 1755

CF10 CFSCHEDULER Overlap

I have a CF10 scheduled task set to run every 2 minutes, though sometimes it takes longer than that to finish. I set up an application variable to prevent the job from running in the event an older job takes longer than 2 minutes. I don't want the scheduled task to overlap. This appears to work. Here is an example of my scheduled task:

<cfoutput>
    Scheduled Task hit: #NOW()#<br />
</cfoutput>

<cfif NOT StructKeyExists(application,"BigJob")>
    <!--- Init the BigJob --->
    <cfset application.BigJob = { isProcessing = FALSE }>   
</cfif>

<!--- Is a BigJob already running? --->
<cfif application.BigJob.isProcessing>  
    <!--- yes it is, abort. --->
    <cfoutput>
        A BigJob is already in process.
    </cfoutput>

    <cfabort>
<cfelse>
    <!--- No it isn't, start processing. --->
    <cfset application.BigJob.isProcessing = TRUE>

    <cfoutput>
        Processing has begun: #NOW()#<br />
    </cfoutput>
</cfif>

<cfscript>

    // sleep for 15 seconds. To simulate processing.
    sleep(15000);

</cfscript>

<cfoutput>
    Scheduled Task complete: #NOW()#
</cfoutput>

<cfset application.BigJob.isProcessing = FALSE>

If I hit this in my browser, I get this output:

Scheduled Task hit: {ts '2013-05-10 16:02:10'}

Processing has begun: {ts '2013-05-10 16:02:10'}

Scheduled Task complete: {ts '2013-05-10 16:02:25'}

If I hit it again in another tab of the same browser 5 seconds later, 10 seconds before the first job finishes, I get this:

Scheduled Task hit: {ts '2013-05-10 16:02:25'}

Processing has begun: {ts '2013-05-10 16:02:25'}

Scheduled Task complete: {ts '2013-05-10 16:02:40'}

This suggests that CF waits for one request to finish before starting the next (note the start and end times).

If I hit the CFM in a different browser, 5 seconds after hitting the first one, I get this expected output:

Scheduled Task hit: {ts '2013-05-10 16:02:18'}

A BigJob is already in process.

My problem is, it appears as if the CFSCHEDULER does not wait for a previous request to finish. CF does wait if the request came from same browser, but it doesn't appear to wait if it's coming from a scheduled task. In CF9, I thought it did.

Is there a better way to prevent scheduled tasks from overlapping in CF10? What is a google-able term for the thing that is preventing my browser from hitting the same page twice? Am I correct that CF9 did wait for a previous task to finish and CF10 does not?

Upvotes: 0

Views: 435

Answers (1)

imthepitts
imthepitts

Reputation: 1647

In my tests, ColdFusion 9 does not execute a task if it is already running. I created a task called "test" that sleeps for 4 minutes but is scheduled to run every 2 minutes. You can see the scheduler log results below:

"Information","scheduler-2","05/10/13","14:34:00",,"[test] Executing at Fri May 10 14:34:00 PDT 2013"
"Information","scheduler-2","05/10/13","14:38:00",,"[test] Rescheduling for :Fri May 10 14:40:00 PDT 2013 Now: Fri May 10 14:38:00 PDT 2013"
"Information","scheduler-0","05/10/13","14:40:00",,"[test] Executing at Fri May 10 14:40:00 PDT 2013"
"Information","scheduler-0","05/10/13","14:44:00",,"[test] Rescheduling for :Fri May 10 14:46:00 PDT 2013 Now: Fri May 10 14:44:00 PDT 2013"
"Information","scheduler-3","05/10/13","14:46:00",,"[test] Executing at Fri May 10 14:46:00 PDT 2013"

Each time, the task took 4 minutes to run and then it was rescheduled for 2 minutes in the future. So the effective interval between runs was actually 6 minutes.

Here is the code I used in the CFM page being executed:

<cfsetting requesttimeout="5000">
<cfscript>
    sleep(240000);
</cfscript>

Here are the task settings I used:

Scheduled Task Settings

If you are getting overlapping executions of scheduled tasks in ColdFusion 10, then as @Leigh mentioned, Ben Nadel's <cflock> solution is a simple way to prevent those overlaps.

Upvotes: 3

Related Questions