I wrote a cronjob class in actionscript 3 during my flight back to Lima from San Francisco. This could help you manage repetitive or single tasks in the future using a cron task syntax.
Here is the cronjob main class:
package utils {
import flash.events.EventDispatcher;
import flash.events.TimerEvent;
import flash.utils.Timer;
import events.CronEvent;
public class Cron extends EventDispatcher {
private var $__timer:Timer = new Timer(60000);
private var $__running:Boolean = false;
private var $__tasks:Array = new Array();
private var $__tasksId:Object = new Object();
public function Cron(){
$__timer.addEventListener(TimerEvent.TIMER, checkTask);
}
public function start():void{
if(!$__running){
var secRes:uint = (60 - ((new Date()).getSeconds() + 1)) * 1000;
var delay:Timer = new Timer(secRes, 1);
delay.addEventListener(TimerEvent.TIMER, function(event:TimerEvent):void{
checkTask((event.clone() as TimerEvent));
$__timer.start();
});
delay.start();
$__running = true;
}
}
public function stop():void{
$__running = false;
$__timer.stop();
}
public function addTask(task:String):void{
task = trim(task);
validateTask(task);
$__tasksId[task.split(" ").pop()] = $__tasks.push(task);
}
public function removeTask(id:String):void{
if($__tasksId[id] == null) throw new Error("Task id " + id + " not found");
$__tasks[$__tasksId[id]] = null;
$__tasksId[id] = null;
delete $__tasksId[id];
}
public function get running():Boolean{
return $__running;
}
private function trim(str:String):String{
return str.replace(/^\s+|\s+$/g, '');
}
private function validateTask(str:String):void{
if(str.split(" ").length != 6) throw new Error("Task format error");
if($__tasks[str.split(" ").pop()] != null) throw new Error("Task id already exists");
}
private function toObject(list:Array):Object{
var res:Object = new Object();
for(var i:uint=0;i<list.length;i++){
if(list[i] != "") res[list[i]] = true;
}
return res;
}
private function $__transform(item:String):*{
if(item.indexOf(",") != -1 && item.indexOf("/") == -1){
return toObject(item.split(","));
}else if(item.indexOf("/") != -1 && item.indexOf(",") == -1){
var items:Array = new Array("0");
for(var i:uint=0;i<(60 - uint(item.split("/")[1]));){
i += uint(item.split("/")[1]);
items.push(i);
}
return toObject(items);
}else{
return item;
}
}
private function $__check(item:*, index:int, array:Array):void{
var date:Date = new Date();
var pieces:Array = item.split(" ");
var mins:* = $__transform(pieces.shift());
var hours:* = $__transform(pieces.shift());
var days:* = $__transform(pieces.shift());
var months:* = $__transform(pieces.shift());
var weekDay:* = $__transform(pieces.shift());
var id:String = pieces.shift();
var dispatch:Boolean = (mins is String) ? (date.getMinutes().toString() == mins || mins == "*"): ((date.getMinutes() + 1).toString() in mins);
dispatch = dispatch && ((hours is String) ? (date.getHours().toString() == hours || hours == "*"): ((date.getHours() + 1).toString() in hours));
dispatch = dispatch && ((days is String) ? (date.getDate().toString() == days || days == "*"): ((date.getDate() + 1).toString() in days));
dispatch = dispatch && ((months is String) ? ((date.getMonth() + 1).toString() == months || months == "*"): ((date.getMonth() + 2).toString() in months));
dispatch = dispatch && ((weekDay is String) ? (date.getDay().toString() == weekDay || weekDay == "*"): ((date.getDay() + 1).toString() in weekDay));
dispatchEvent(new CronEvent(CronEvent.TASK, id));
}
private function checkTask(event:TimerEvent):void{
$__tasks.forEach($__check);
}
}
}
And here is the CronEvent class:
package events {
import flash.events.Event;
public class CronEvent extends Event {
public static const TASK:String = "task";
public var id:String = "";
public function CronEvent(type:String, id:String=""){
this.id = id;
super(type);
}
override public function clone():Event{
return new CronEvent(type, id);
}
}
}
Here is how you can use it:
import utils.Cron;
import events.CronEvent;
var c:Cron = new Cron();
c.addEventListener(CronEvent.TASK, taskHandler);
function taskHandler(event:CronEvent):void{
trace ("The task id is: " + event.id);
}
c.addTask("* * * * * mainID"); // repetitive task (every minute)
c.addTask("0 0 * * * otherID"); // repetitive task every day at 00:00
c.start();
I haven't had the chance to test it carefully. Please let me know if you find anything.
--fernando
