Module: core/schedulers

This module is used to schedule the future execution of programmed tasks.

Structure of schedulers

The module has 3 kind of elements :
  • Schedulers. Each scheduler runs in its own process seperated from the rest of the supervision. Each process can have multiple functions and triggers. If one of the task execution fails with unhandled exception, then its process is terminated and rebooted after a short delay (max. 30 seconds). Note that an error in the scheduled tasks does not affect the other parts of the system, nonetheless if two tasks in the same scheduler are triggered with less than 30 seconds between the two, an unhandled exception in the first task could prevent the second task of being executed. Hence, it is good to test the tasks and control that no errors are thrown by the custom functions.
  • Functions. Standard javascript function code (name and body). Those can be scheduled for later execution, or immediately executed for testing.The javascript function are bound to the peers API, so that the API is accessible by using "this" keyword inside the function body.
  • Triggers. Triggers objects are refered to using their name property. Those define when (which moment in time) the choosen function is executed. The different trigger time formats are described in the next section below.


Time formats

There is different possible time formats (i.e. the "when" property of the schedule object):
  • Javascript Date Object (https://www.w3schools.com/jsref/jsref_obj_date.asp). new Date(new Date().getTime() + 24 * 60 * 60 * 1000) executes once 24 hours later.
  • String date format. '15:00' executes every day at 15:00
  • String cron format (https://en.wikipedia.org/wiki/Cron). '* * * * *' executes every minute
  • Interval time in milliseconds. i.e. 1000*60*60 executes every hour. Note that the execution time is not random but rounded to the milliseconds. As an example, if the interval time is 1000*60*60 (3600000), then the next execution date is rounded to the hour using the modulo operation on the milleseconds : new Date(Date.now() - Date.now()%3600000 + 3600000).
  • Special values / shortcuts. Can be used to execute a function when the system/scheduler reboots/restarts.
  • An array of multiple combinations. i.e. [new Date(new Date().getTime() + 24 * 60 * 60 * 1000), '15:00','* * * * *', 1000*60*60] executes once 24 hours later, every day at 15:00, every minute, and every hour.
Below some examples for the string date format, cron, and special values (system reboot):

Date format (string): 

 ________English__________________Full date___________Concise date___
|                          |                     |                   |
| Christmas 2016 at noon   | 12:00:00 25.12.2016 | 12:00 25.12.2016  |
| New year 2016            | 00:00:00 01.01.2016 | 1.1.2016          |
| Every new year           | 00:00:00 01.01.**** | 1.1.*             |
| Every first day of month | 00:00:00 01.**.**** | 1.*.*             |
| Every day at 13:00       | 13:00:00 **.**.**** | 13:00             |
| Every hour               | **:00:00 **.**.**** | *:0               |
| Every minute             | **:**:00 **.**.**** | *:*               |
| Every 10 minutes         | **:*0:00 **.**.**** | *:*0              |
| Every second             | **:**:** **.**.**** | *:*:*             |
``````````````````````````````````````````````````````````````````````

Cron format (string): 
 *    *    *    *    *
 ┬    ┬    ┬    ┬    ┬
 │    │    │    │    |
 │    │    │    │    └ day of week (0 - 7) (0 or 7 is Sun)
 │    │    │    └───── month (1 - 12)
 │    │    └────────── day of month (1 - 31)
 │    └─────────────── hour (0 - 23)
 └──────────────────── minute (0 - 59)


 __________English________________Cron_____
|                           |              |
| New year                  | 0 0 1 1 *    |
| Every first day of month  | 0 0 1 * *    |
| Every sunday at midnight  | 0 0 * * 0    |
| Evey day at midnight      | 0 0 * * *    |
| Every hour                | 0 * * * *    |
| Every minute              | * * * * *    |
| Every 5 minutes           | * /5 * * * * |
````````````````````````````````````````````

Special values (string): 

 __________English_________________Value___
|                               |          |
| When the system is rebooted   | @reboot  |
| When the scheduler is started | @restart |
```````````````````````````````````````````



Use



//Basic use cases. 

peers('supervision').require('schedulers', function(err, schedulers){
	
	//inserts a new scheduler process in the system, and specifies if it is active or not. 
	schedulers.insertScheduler({
		name :  'mySchedule',
		active : false
	}, function(err){...})
	
	//starts the scheduler process (and set active to true).
	schedulers.startScheduler('mySchedule',function(err){...})
	
	// other scheduler functions : 
	// schedulers.getSchedulers(function(err, schedulers)){...}
	// schedulers.getScheduler(function(err, scheduler)){...}
	// schedulers.stopScheduler('mySchedule',function(err)){}
	// schedulers.deleteScheduler('mySchedule')
	
	//inserts a function in the scheduled tasks system. 
	schedulers.insertFunction('mySchedule', 
		function myTask(callback){ //note that the function should be uniquely named (anonymous functions are not supported for insertion).
			var peers = this  //the peers API is bound to the function. 
			peers('supervision').require('gateways', function(err, gateways){
				if(err){
					if(callback) callback(err)
				}else{
					gateways.writeValue('1/1/1', 0, callback) //write a 0 on KNX address 1/1/1
				}
			})
		},
		function(err){
			if(err){
				console.error("function insertion failed")
			}else {
				console.log("function myTask was succsesfully inserted")
			}
		}
	)
		

	//executes a function immediately for testing or from another module (visualization, logic, etc..)
	schedulers.executeFunction('mySchedule','myTask',function(err){
		if(err){
			console.log("execution of the function failed",err)
		}
	})
	
	//deletes a function : 
	schedulers.deleteFunction('mySchedule','myTask', function(err){..})
	
	
	//triggers the execution of a function
	schedulers.insertTrigger('mySchedule',{
		name 	 	: 'myTrigger',
		function 	: 'myTask',	//	links to an existing function.
								//	Could be an array of functions : ['myTask', 'mySecondTask'], 
								//	or an object with additional options like function arguments and delay in ms : 
								//	{
								//		'myTask' : {delay : 0, arguments : [...]}, 
								//		'mySecondTask' : {delay : 1000*60*60, arguments : [...]}
								//	}. so that the second task ('mySecondTask') would be executed one hour after the trigger. 
		when	  	: '15:00', 	// see above for the possible time formats. Here it triggers every day at 3pm. 
		active	  	: true,		// specifies if the trigger is active or not.
	}, function(err){
		if(err) console.error(err) // if schedule insertion fails.
	})
	
	//list all the triggers 
	schedulers.getTriggers('mySchedule', function(err,triggers){
		// triggers : {
		//    'myTrigger' : {...}	
		// 	  'mySecondTrigger' : {...}
		// }
	})
	
	//get a specific trigger information
	schedulers.getTrigger('mySchedule','myTrigger', function(err,trigger){
		// trigger properties : trigger.name, trigger.function, trigger.when, trigger.active.
	})
	
	//get the next executions. Maximum 1000, default : 10
	schedulers.getTriggerNext('mySchedule', 'myTrigger', 10, function(err, dates){
		// dates is an array containing the next dates of execution. (here 10 next dates)
		// dates are chronologically sorted
	})
	
	//get the past executions.  Maximum 1000, default : 10.
	schedulers.getTriggerPast('mySchedule','myTrigger', 10, function(err,dates){
		// dates is an array containing the past dates of execution. (here 10 past dates)
		// dates are chronologically sorted
	})
})


Events emitted by the scheduler module
//for schedulers : 
schedulers.on('schedulerInserted',function(newScheduler){ ... })
schedulers.on('schedulerDeleted', function(deletedScheduler){ ... })
schedulers.on('schedulerState',   function(schedulerName, state){ 
	// where state equal to 'connecting', 'connected', or 'disconnected' 
})  

//for functions : 
schedulers.on('functionInserted',function(schedulerName, newFunction){ ... })
schedulers.on('functionUpdated', function(schedulerName, updatedFunction, oldFunction){ ... })
schedulers.on('functionDeleted', function(schedulerName, deletedFunction){ ... })
     
//for triggers :                                   
schedulers.on('triggerInserted', function(schedulerName, newTrigger){})
schedulers.on('triggerUpdated' , function(schedulerName, updatedTrigger, oldTrigger){})
schedulers.on('triggerDeleted' , function(schedulerName, deletedTrigger){})


Memory use caution
In memory limited environnements (<= 1go of ram memory. e.g. raspberry pi, other embedded computers), it is advised to have only one or few schedulers (processes) to manage all scheduled tasks.

Methods

(static) cleanBrokenFunctions(schedulerName, triggerName, callback)

Removes in all triggers the broken references to non-existant functions.
Parameters:
Name Type Description
schedulerName string the name of the scheduler process.
triggerName string the name of the trigger.
callback function callbacks if the operation succeed and the deleted broken function links. function(err, brokenFunctions){...}

(static) deleteFunction(schedulerName, functionName, callback)

Deletes a function. Once deleted, the function is lost and cannot be retrieved.
Parameters:
Name Type Description
schedulerName string the name of the scheduler process
functionName string the name of the function to delete.
callback function callbacks if the deletion succeed or failed. function(err){if(err){console.error("function deletion failed",err)}}

(static) deleteScheduler(schedulerName, callback)

Deletes a scheduler.
Parameters:
Name Type Description
schedulerName string name of the scheduler process.
callback function callbacks if the deletion succeed or failed. function(err){ if(err) {console.error("deletion failed",err)} }

(static) deleteTrigger(schedulerName, triggerName, callback)

Deletes a trigger.
Parameters:
Name Type Description
schedulerName string the name of the scheduler process.
triggerName string the name of the trigger to udpate.
callback function callbacks if the deletion failed or succeed.

(static) executeFunction(schedulerName, functionName, a1, a2, an)

Executes a function for test or from somewhere else (visualization, logic module, etc..). If a callback is defined, it should be the last argument.
Parameters:
Name Type Description
schedulerName string the name of the scheduler process.
functionName string the name of the function.
a1 value first argument.
a2 value second argument.
an value n'th argument.

(static) getBrokenFunctions(schedulerName, triggerName, callback)

Gets for one trigger the potential references to non-existant functions.
Parameters:
Name Type Description
schedulerName string the name of the scheduler process.
triggerName string the name of the trigger.
callback function callbacks the potential broken function links. function(err, brokenFunctions){...}

(static) getFunction(schedulerName, functionName, callback)

Gets the function identified by its scheduler name and its name.
Parameters:
Name Type Description
schedulerName string the name of the scheduler process
functionName string the name of the function.
callback function callbacks the function or an error if the operation fails. function(err, myFunction){...}

(static) getFunctions(schedulerName, callback)

Gets all the functions defined in a scheduler. The functions are returned in the callback as an object with function names as keys and functions as values.
Parameters:
Name Type Description
schedulerName string the name of the scheduler process
callback function callbacks the functions or an error if the operation fails. function(err, functions){...}

(static) getScheduler(schedulerName, callback)

Returns in the callback the scheduler state / information.
Parameters:
Name Type Description
schedulerName string name of the scheduler process.
callback function callbacks in an object the name, if the process is active or not, and its state (connecting/ connected / disconnected).

(static) getSchedulers(callback)

Returns the schedulers in an object of this form :

{	
	schedulerA : {
		name : 'schedulerA',
		state : 'disconnected',
		active : 0
	},
	schedulerB : {
		name : 'schedulerB',
		state : 'connected', 
		active : 1
	},
	schedulerC : {
		name : 'schedulerC',
		state : 'connecting', 
		active : 1
	}
}
Parameters:
Name Type Description
callback function function used to return the schedulers. function(err, schedulers){...}

(static) getTrigger(schedulerName, triggerName, callback)

Gets the trigger object by its scheduler name and (trigger) name.
Parameters:
Name Type Description
schedulerName string the name of the scheduler process
triggerName string the name of the trigger.
callback function callbacks the trigger with specified name or an error if the operation failed.

(static) getTriggerNext(schedulerName, triggerName, numberOfNexts, callback)

Gets the next executions of the specified trigger.
Parameters:
Name Type Description
schedulerName string the name of the scheduler process.
triggerName string the name of the trigger.
numberOfNexts string optional parameter. Specify the number of futures executions to return (max 100). If the parameter is omitted, it is by default 1.
callback function callbacks the next executions in an array of dates or a single date if numberOfNexts is 1. function(err, nextExecutions){...}.

(static) getTriggerPast(schedulerName, triggerName, numberOfPasts, callback)

Gets the past executions of the specified trigger. Only the triggers that were effectively executed are returned.
Parameters:
Name Type Description
schedulerName string the name of the scheduler process.
triggerName string the name of the trigger.
numberOfPasts string optional parameter. Specify the number of past executions to return (max 100). If the parameter is omitted, it is by default 1.
callback function callbacks the next executions in an array of dates or a single date if numberOfNexts is 1. function(err, nextExecutions){...}.

(static) getTriggers(schedulerName, callback)

Gets all the triggers defined in a scheduler. The triggers are returned in the callback as an object with trigger names as keys and triggers (object) as values.
Parameters:
Name Type Description
schedulerName string the name of the scheduler process
callback function callbacks the triggers or an error if the operation fails. function(err, triggers){...}

(static) insertFunction(schedulerName, newFunction, callback)

Inserts a new function. Once inserted, the function can be associated with triggers.
Parameters:
Name Type Description
schedulerName string the name of the scheduler process
newFunction function the new function (javascript function bound to the API). The function must have a name.
callback function callbacks if the insertion of the new function failed or succeed. function(err){if(err){console.error("function insertion failed",err)}}

(static) insertScheduler(newSchedulerName, callback)

Inserts a new scheduler process. Initially the inserted scheduler is not started automatically. To start a scheduler, use the schedulers.startScheduler function.
Parameters:
Name Type Description
newSchedulerName string name of the new scheduler process.
callback function callbacks if the insertion succeed or failed. function(err){ if(err) {console.error("insertion failed",err)} }

(static) insertTrigger(schedulerName, newTrigger, callback)

Inserts a new trigger in a scheduler process.
Parameters:
Name Type Description
schedulerName string the name of the scheduler process.
newTrigger object the name of the scheduler process.
callback function callbacks if the insertion failed or not. function(err){if(err){console.error("trigger insertion failed",err)}}

(static) startScheduler(schedulerName, callback)

Starts a scheduler process.
Parameters:
Name Type Description
schedulerName string name of the scheduler process.
callback function callbacks if the scheduler process could be started or not. function(err){ if(err) {console.error("could not start the scheduler process",err)} }

(static) stopScheduler(schedulerName, callback)

Stops a scheduler process.
Parameters:
Name Type Description
schedulerName string name of the scheduler process.
callback function callbacks if the scheduler process could be stopped or not. function(err){ if(err) {console.error("could not stop the scheduler process",err)} }

(static) updateFunction(schedulerName, updatedFunction, callback)

Updates a function.
Parameters:
Name Type Description
schedulerName string the name of the scheduler process
updatedFunction function the new version of an existing Javascript function. The updated function must have the same name as its previous definition.
callback function callbacks if the update succeed or failed. function(err){if(err){console.error("function update failed",err)}}

(static) updateTrigger(schedulerName, updatedTrigger, callback)

Updates a trigger.
Parameters:
Name Type Description
schedulerName string the name of the scheduler process.
updatedTrigger object the updated trigger identified by updatedTrigger.name.
callback function callbacks if the tr succeed or failed. function(err){if(err){console.error("trigger update failed",err)}}