Appearance
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:
Alias | Description | Expression |
---|---|---|
@minutely | Run once a minute. | 0 * * * * * * |
@hourly | Run once an hour. | 0 0 * * * * * |
@daily | Run once a day. | 0 0 0 * * * * |
@weekly | Run once a week. | 0 0 0 * * 0 * |
@monthly | Run once a month. | 0 0 0 1 * * * |
@annually | Run once a year. | 0 0 0 1 1 * * |
@yearly | Run once a year. | 0 0 0 1 1 * * |
More examples:
0 0 12 * * * *
- every day at noon10 */5 * * * 0 *
- at 10 seconds past the minute, every 5 minutes, only on Sunday0 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:
- 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.
- Execute Embed LEDR Pulse and LEDG Pulse Pulse requests, and send responses using
WebsocketMessaging
andWebsocketMessaging
,MqttMessaging
messaging services respectively.
json
{
"...": "...",
"task": [
{
"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.