Creating A Centralized Point Of Entry For ColdFusion Scheduled Tasks

Posted February 21, 2007 at 1:29 PM by Ben Nadel

Tags: ColdFusion

I have never been a huge fan of ColdFusion's scheduled tasks. That's just an odd fear based on the fact that I have to rely on something outside of my applications. But, the fact is, scheduled tasks are essential if you want to do anything on a scheduled basis that is NOT triggered by user actions. I am also not a huge fan of creating / modifying / deleting scheduled tasks using the ColdFusion CFSchedule tag as it tends to leave phantom tasks running until the ColdFusion service gets restarted.

In order to deal with all of that emotionally, what I have started doing is creating a single point of entry for scheduled tasks in my ColdFusion applications. I have a single ColdFusion template that launches all of my application's scheduled tasks:

  • <!--- Kill extra output. --->
  • <cfsilent>
  •  
  • <!---
  • Send girlfriend random text message so that
  • she knows that I am thinking about her.
  • --->
  • <cfhttp
  • url="./tasks/send_random_text_message.cfm"
  • method="GET"
  • timeout="1"
  • throwonerror="false"
  • />
  •  
  • <!--- Clean up temp files. --->
  • <cfhttp
  • url="./tasks/purge_temp_files.cfm"
  • method="GET"
  • timeout="1"
  • throwonerror="false"
  • />
  •  
  • <!--- Send out scheduled emails. --->
  • <cfhttp
  • url="./tasks/scheduled_emails.cfm"
  • method="GET"
  • timeout="1"
  • throwonerror="false"
  • />
  •  
  • </cfsilent>
  •  
  • <!--- We are done running tasks. --->
  • Done.

As you can see, this single point of entry turns around and launches additional scheduled tasks using CFHttp calls. Each CFHttp call is given one second to execute before it times out (without error) and the current page moves onto the next task.

The down side to this is that each task has to know a bit more information. Tasks cannot assume they are only run once every N hours or days. Since this one point of entry is responsible for every scheduled task on the site, it must run as often as the smallest required time interval. This means that a task designed to run once a day might end up getting called once every 15 minutes. That task has to know to ONLY run once per day even though it is "asked" to run much more often.

The up side to this, however, is that you only need to set up one scheduled task in the ColdFusion administrator (per application). If you have any additional scheduled task requirements all you have to do is update your point of entry. You never need to go back to the ColdFusion administrator for task set up for the application (unless, of course, you need to increase / decrease the interval at which the task runs).

So far, I have used this with great success. And, I find that it forces me to write much better, smarter scheduled tasks that don't rely on the scheduled task interval.




Reader Comments

Feb 21, 2007 at 1:59 PM // reply »
4 Comments

I like this idea, and I think the cons that you brought up could be remedied with some magic...I am going to investigate more into this design because you and I share the same fears.


Feb 21, 2007 at 2:07 PM // reply »
11,307 Comments

Derek,

I agree. For instance, one of the sample tasks was an automated email sender. If you were grabbing emails out of a database, you could certainly have a field for date_last_sent which could be updated / read for task execution.

Let me know what kinds of stuff you come up with.


Feb 21, 2007 at 2:32 PM // reply »
18 Comments

Ben,

Take a look at this as well. Another way to deal with Scheduled Tasks:

http://labs.redbd.net/projects/cfcron.cfm

Sami


Feb 21, 2007 at 2:43 PM // reply »
11,307 Comments

Sami,

That looks pretty cool. I have not seen that before. I like that the CFC handles the "interval" hand-holding. Very cool.


Feb 22, 2007 at 3:17 AM // reply »
6 Comments

The other downside is that if you don't put try-catch in each item if one fails they all fail. Also if you put a bug in your script, none run.


Feb 22, 2007 at 6:27 AM // reply »
11,307 Comments

Chris,

The CFTry / CFCatch is not necessary since the failure will happen in the page being called via CFHttp, not the primary task page. If the page getting called fails, the only thing the calling page knows is that the error message gets returned in the CFHTTP.FileContent attribute; it sees it as just some text... not an error.

But yes, if there is an error in primary page, some or all will fail to run. But of course, that is what testing is for :)


Feb 22, 2007 at 10:01 AM // reply »
95 Comments

Ben,

neat idea. I also like the idea of sending your girlfriend text messages (even if it's a fictional idea, he he). On that note, you should replace the "girlfriend" with a variable so it could be used for a "wife" also, lol. Keep up the good work.


Jun 30, 2009 at 4:37 PM // reply »
29 Comments

Definitely a tried and true strategy for scheduling.

Especially for related/dependent tasks.
- Error handling between steps
- Success required/optional
- Retry 10 times, then quit
- Do if not done already today, this hour
- Pick up where left off, before error
- Avoid multiple exec if still running

It's simple enough to set up separate sched tasks for different purposes.
- Hourly custom session mgmt cleaning
- Daily batch imports/exports
- Persistent loop/daemon (restarted if not running)

The imagination abounds.


Jul 1, 2009 at 8:27 AM // reply »
11,307 Comments

@Alex,

I never even thought of doing the "Try 10 times and then quit" aspect. Nice suggestion!


Jul 27, 2009 at 5:24 AM // reply »
3 Comments

Hi Ben,

I keep getting a duplication on processing when this event happen in my server.log...any of you guys have any idea about this. I know that neo-cron is where you put the scheduled task parameter on it but why is it modified without my intervention.

This is what i got in the server.log :-

neo-cron.xml has been modified . Reloading the service coldfusion.scheduling.CronServiceImpl@13de08a

URGENT ASSISTANT required on this matter.

Thanks....


Jul 27, 2009 at 8:09 AM // reply »
11,307 Comments

@Wan,

I used to get duplicate tasks being run when I messed around with CFSchedule. How are you creating the scheduled tasks?


Jul 27, 2009 at 1:07 PM // reply »
3 Comments

@Ben,

Everything is ok until this thing come out from no where and it is started to duplicate by itself.

I pumped in a lot of data into the scheduled task for every 15 seconds interval. Do you think this is the caused of it. Or there is any other reason why it became like this.


Jul 27, 2009 at 1:16 PM // reply »
11,307 Comments

@Wan,

I am surprised that you can get a scheduled task to run every 15 seconds. I believe that the last time I tried it, it had to be done ever 60 seconds minimum. Are you running several scheduled tasks?


Jul 27, 2009 at 8:54 PM // reply »
3 Comments

@Ben,

I think that will not a big suprised since you can set it at CFSCHEDULE but the problem is only on processing burden to the server.

Yeap...there is several scheduled tasks running at the same time.

Ben, I got another question for you...Let say if I got two machines with the same serial number, will it gives any impact to my scheduled task. Because keep getting the remark in the server log 'Same Serial Number found on another CF server - server may be out of compliance'. Is it considered clustered? I read somewhere in the internet that if i have clustered the coldfusion...I might got a problem on the neo-cron.xml which causing the duplication.


Aug 5, 2009 at 7:47 PM // reply »
11,307 Comments

@Wan,

Once you go past one server, you get out of my area of understanding. I know very little about clustering. Sorry.


Aug 26, 2009 at 11:23 AM // reply »
4 Comments

@Ben,

Any reason you know of that AJAX would not work from a scheduled tasks? Since JS is client side and the scheduled task is being called from the server side, do you think there is a bit of an issue?

There is the RESOLVE URL attribute of the scheduled task.

What are your thoughts?


Aug 26, 2009 at 11:33 AM // reply »
29 Comments

@Jeff

Ajax would not work.

HTTP responses, including JavaScript are not browsed by the task scheduler.

Scheduled tasks are a way of running CF as generic scripts. Not HTTP requests/responses.

No?


Aug 26, 2009 at 11:49 AM // reply »
4 Comments

@Anyone

RE: scheduled task and ajax (read previous two post) ... not working ... yes, makes total sense.

Would CFTHREAD be a solution? There are many tasks being fired off with AJAX and no response back to the parent call. The AJAX was being used to just fire off the tasks independently. What about CFTHREADING the task since none of the data is dependent upon the other?

Note: This tasks is usually run when the server has very low traffic. Also, if you loaded up the server with 20 CFTHREAD calls, would it operate similar to AJAX in that it would initially load up the available threads and then the remaining would stack up until threads were available?


Sep 2, 2009 at 10:07 AM // reply »
11,307 Comments

@Jeff,

Yes, CFThread would work, and in fact, I have created scheduled task sub-processes in this way. You have the single point of entry, and then each subsequent task is launched using a CFThread. You just have to be careful about passing data into it.


Apr 29, 2011 at 2:03 AM // reply »
4 Comments

Hi ben, I have created as Scheduled task in my admin Programatically, But it shows "Connecction Failue: Status Code Unavaliablle" Error!

i am trying something like this

<cfif isScheduledTaskExists("taskname")>
<cfscedule action="run" name="taskname">
<cfelse>
<cfschedule action="update" httprequest="yes" url="/common/files/coldfusion/action.cfm" resolveurl="yes"> <!--- Other attributes being added to it --->
</cfif>

Can You guide a bit on this


May 23, 2011 at 8:49 AM // reply »
18 Comments

For this one particular app, I have set up my scheduled tasks in CFAdministrator a little differently, setting up one for each interval I need (2 minutes, 15 minutes, 4 hours, one day) and each task calls it's own function in an Automation.cfc controller. I can then drop cfhttp calls into whatever interval function I need, and I'm only returning to cfadmin if I need a different interval (or different run windows, etc.) configured.

I also created an init() function in my Automation controller that uses CFSCHEDULE tag to "update" (create) the intervals in the cfadmin on application start... so I'm rarely going to cfadmin at all... so this one file pretty much spells out exactly what the automation config is for the app, from creating the intervals to outlining exactly what happens at each interval.

My question is regarding your decision to set each cfhttp call to a one-second timeout. According to the (CF8) docs:

"timeout" : Value, in seconds, that is the maximum time the request can take. If the time-out passes without a response, ColdFusion considers the request to have failed.

I have a few interval functions that need to do several CFHTTP calls in a row. If I set the timeout to 1 second and the throwonerror to false, can I assume that the actual call still RUNS, I've essentially just told the app not to wait around for it, and move on to the next CFHTTP call? This doesn't have an adverse effect on the actual page being called... the server still completely processes that request separately?

I think I know the answer, but thought it would be helpful to have that clarified here....

Thanks as always... seems whenever I'm Googling for information like this, your name always comes up. ;)



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Jun 18, 2013 at 2:44 AM
For Better: The Love Scale Quiz Designed By Dr. Hatkoff
I have read your problem. My best friend faced the same problem when she was in her college. It's quite difficult to solve when someone don't to solve the whole thing. But be strong and hope for the ... read »
Jun 18, 2013 at 2:31 AM
SOTR 2013 - The Best Conference I Never Went To
I keep watching it, should keep me happily distracted until SotR14 ;) ... read »
Jun 17, 2013 at 9:45 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, As I was reading what you wrote, it occurred to me that maybe I do something similar to that in some of my client-side code. In an application I'm working on, there are a bunch of unrelated ... read »
Jun 17, 2013 at 9:36 PM
Object Thinking By David West
@Jonah, Please, don't feel bad at all. I appreciate all that you have contributed to the conversation. And, the more points of view I get, the more confident I am that I will some day, some how und ... read »
Jun 17, 2013 at 9:32 PM
Object Thinking By David West
@Paul, I definitely have a mental hurdle when it comes to discovering better design over time. My brain has this insane urge to just understand how you do something right the first time :) But, eve ... read »
Jun 17, 2013 at 9:29 PM
SOTR 2013 - The Best Conference I Never Went To
I just had to watch this again - amazing :) ... read »
Jun 17, 2013 at 9:28 PM
Working With Inherited Collections In AngularJS
@Ali, You are right - it is confusing. I should have just named it "saveForm()" or "submitForm()" or something to that effect. Then, the saveForm() method could have simply vali ... read »
Jun 17, 2013 at 9:27 PM
Working With Inherited Collections In AngularJS
@Samuel, Good question - that was also bothering me when I wrote the code. Yes, I could have moved it up into AppController. The reason that I didn't for this demo was that I didn't want the AppCon ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools