Skip to content

Scheduler

The scheduler feature allows users to schedule JSON API requests as jobs for the daemon to execute automatically. Tasks can be configured to execute jobs at specific times. Each task can be activated (scheduled) or deactivated (unscheduled).

New in v2.4

  • tasks can be easily edited via the EditTask request
  • tasks can now be started and stopped using the StartTask and StopTask requests
  • tasks can now be set to start on launch automatically
  • tasks can now have user-defined descriptions
  • tasks now use UUID v4 as IDs instead of integers
  • one-shot tasks now require ISO 8601 datetime timestamp format
  • cron time is now accepted in string format

Anatomy of a task

Each task record is comprised of a client ID, task ID, description, time specification, message(s), and their respective messaging services, persistence, and startup policy. Client and task IDs identify a single unique task record.

See the example below:

json
{
	"clientId": "SchedulerMessaging",
	"taskId": "a6059e0c-221e-4bfc-8d3a-cc606fce4ca3",
	"description": "example task",
	"task": [
		{
			"message": {
				"mType": "iqrfEmbedLedr_Pulse",
				"data": {
					"msgId": "testEmbedLedr",
					"req": {
						"nAdr": 1,
						"param": {}
					},
					"returnVerbose": true
				}
			},
			"messaging": [
				"WebsocketMessaging"
			]
		}
	],
	"timeSpec": {
		"cronTime": "",
		"exactTime": false,
		"periodic": true,
		"period": 20,
		"startTime": ""
	},
	"persist": true,
	"enabled": true
}

Client ID

Client ID is an identifier for a task-handling service. It is also used to group a subset of all existing tasks for List and RemoveAll requests. For Scheduler tasks, set the clientId property to SchedulerMessaging value to ensure that responses are sent.

Task ID

Task ID is a unique identifier (UUID v4 string) of a task record. While the task ID property is a required component of a task, it does not need to be included in the task specification. If a task record is created with the taskId property, the specified ID is validated and used, unless another task record with the same ID already exists. If the taskId property is not present, Daemon generates a new random ID for this task record.

Description

Task description serves no purpose other than user-defined notes for marking or labeling tasks. Task description is optional and does not need to be defined in the task record. Use the description property to set task description.

Time specification

Users can use the time specification to specify when and under what conditions jobs should be executed. To configure job execution conditions, use the timeSpec object. Note that all properties of the timeSpec object need to be set; otherwise, it is not considered a valid configuration. There are 3 different time-based conditions for job execution:

1. One-shot - Execute job once at a specified time.

One-shot is a simple "fire and forget" style job. When the job is executed, the task itself is removed.

Its execution time is specified by an ISO 8601 date-time timestamp. To configure a task as one-shot task, use the exactTime property. To specify execution time, use the startTime property. Note that while Daemon accepts ISO 8601 timestamps with offsets, it handles time in UTC, and responses will also contain timestamps in UTC.

Example timeSpec object:

json
{
	"exactTime": true,
	"startTime": "2023-1-1T12:00:00Z",
	"periodic": false,
	"period": 0,
	"cron": ""
}

Executes job once on January 1st, 2023 at 12:00:00 UTC.

More examples:

  • 2023-1-1T12:00:00.550Z
  • 2023-1-1T13:00:00+01:00
  • 2023-1-1T06:00:00.250-06:00

2. Periodic - Execute job repeatedly after a certain period of time.

Periodic tasks create jobs at fixed intervals, specified by a period. To configure a task as a periodic task, use the periodic property. The period is specified in seconds by the period property and needs to be at least 1 second.

Example timeSpec object:

json
{
	"exactTime": false,
	"startTime": "",
	"periodic": true,
	"period": 60,
	"cron": ""
}

Executes job every 60 seconds.

3. cron - Execute job periodically at fixed times, intervals or dates.

cron expressions allow for more flexible and versatile scheduling of jobs. Daemon supports extended 7-field cron expression. The supported fields are: seconds, minutes, hours, days of month, months, days of week and years. A cron expression can be specified using the cron property. This property can either be a string or an array of 7 string elements (one string per field).

The implementation supports comma (list of items), dash (inclusive range), and slash (step) characters.

Days of month and days of week fields do not support the special characters L and W.

Example timeSpec object:

json
{
	"exactTime": false,
	"startTime": "",
	"periodic": false,
	"period": 0,
	"cron": "10 */1 * * * * *"
}

Execute job at 10 seconds past every minute.

json
{
	"exactTime": false,
	"startTime": "",
	"periodic": false,
	"period": 0,
	"cron": [
		"10",
		"*/1",
		"*",
		"*",
		"*",
		"*",
		"*"
	]
}

Equivalent cron expression in array of strings format.

Additionally, Daemon also supports the following cron aliases:

AliasDescriptionExpression
@minutelyRun once a minute.0 * * * * * *
@hourlyRun once an hour.0 0 * * * * *
@dailyRun once a day.0 0 0 * * * *
@weeklyRun once a week.0 0 0 * * 0 *
@monthlyRun once a month.0 0 0 1 * * *
@annuallyRun once a year.0 0 0 1 1 * *
@yearlyRun once a year.0 0 0 1 1 * *

More examples:

  • 0 0 12 * * * * - every day at noon
  • 10 */5 * * * 0 * - at 10 seconds past the minute, every 5 minutes, only on Sunday
  • 0 0 8-15,20 * 1 * * - every hour, at 8 AM through 3 PM and at 8 PM, only in January

Message(s) and messaging services

Each task can carry one or more request messages to be sent when a job is created and executed. You can also specify which messaging services will be used to send responses.

Messages are stored in the task property. The property can either be an object (single message) or an array of objects (multiple messages). Each task object contains message and messaging properties. The message property is a JSON API request to send when a job is created and executed. The messaging property is used to specify one (string) or more (array of strings) messaging services to be used to send response(s).

The default available messaging services are MqMessaging, MqttMessaging and WebsocketMessaging. Additional messaging services can be configured by the user via the IQRF Gateway Webapp messaging configuration page or REST API.

Examples:

  1. Execute Embed LEDR Pulse request and send response using WebsocketMessaging messaging service.
json
{
	...
	"task": {
		"message": {
			"mType": "iqrfEmbedLedr_Pulse",
			"data": {
				"msgId": "testEmbedLedr",
				"req": {
					"nAdr": 1,
					"param": {}
				},
				"returnVerbose": true
			}
		},
		"messaging": [
			"WebsocketMessaging"
		]
	}
	...
}

task as object.

  1. Execute Embed LEDR Pulse and LEDG Pulse Pulse requests, and send responses using WebsocketMessaging and WebsocketMessaging, MqttMessaging messaging services respectively.
json
{
	...
	"task": [
		{
			"message": "message": {
				"mType": "iqrfEmbedLedr_Pulse",
				"data": {
					"msgId": "testEmbedLedr",
					"req": {
						"nAdr": 1,
						"param": {}
					},
					"returnVerbose": true
				}
			},
			"messaging": [
				"WebsocketMessaging"
			]
		},
		{
			"message": {
			"mType": "iqrfEmbedLedg_Pulse",
				"data": {
					"msgId": "testEmbedLedg",
					"req": {
						"nAdr": 1,
						"param": {}
					},
					"returnVerbose": true
				}
			},
			"messaging": [
				"MqttMessaging",
				"WebsocketMessaging"
			]
		}
	]
}

task as array of object. Note that task array with a single object is functionally equivalent to task object.

Persistence

Persistent tasks persist after a Daemon or Gateway reboot. Persistent tasks are stored on the filesystem, and in memory while Daemon is running. Non-persistent tasks are only stored in Daemon memory and will cease to exist upon Daemon or Gateway shutdown or reboot. To create a persistent task, set the persist property to true.

Startup policy

Specifies whether a task should be active on Daemon startup. To create a task that is scheduled on startup, set the enabled property to true.

Scheduling status

The current state (scheduled / not scheduled) of a task is presented by the active property. This is a read-only, runtime property and is only present in GetTask and List responses.

Managing tasks

There are handful of ways to create, edit or delete tasks.

Manually

Tasks are stored on filesystem in /var/cache/iqrf-gateway-daemon/scheduler as JSON files. A possible, but rather cumbersome way to manage tasks is to do it manually on the filesystem. Simply add, modify, or delete a JSON file to create, edit, or delete a scheduler task. Note that the Daemon service needs to be restarted for these changes to take effect.

Daemon API

Tasks can be managed via the Daemon Scheduler API. In this case, the Daemon service does not need to be restarted. Each task can also be activated and deactivated at runtime using the StartTask and StopTask requests, respectively.

Webapp

Finally, tasks can be managed using the Scheduler configuration page of the IQRF Gateway Webapp UI, which communicates with Daemon via the Daemon JSON API or via the REST API. If the Daemon service is unavailable, users can still add, edit, or delete tasks via the Webapp UI, but cannot activate or deactivate tasks, and the Daemon service needs to be restarted for changes to take effect.

Known limitations

Scheduler does not analyze tasks to estimate how long a job will take, and as such, it does not stagger tasks. This means that it is possible to schedule enough tasks to fill up the request message queue, rendering the Daemon JSON API unresponsive as requests are ignored when message the internal queue is full. To deal with this situation, stop the Daemon service, delete tasks from the filesystem or via the IQRF Gateway Webapp UI, and start the service back up.