Schedules Module
The ScheduleModule is a server-side only module, that provides the feature to run methods on a time-based manner, either for a specific point in time (Schedule), or in a certain time interval (Cycle) using attributes.
Feature Overview
- Declare schedule type using attributes ✅
- Track history of either type ✅
- Perform "catch up" on server start for missed runs ✅
History / Catchup
Schedules and cycles offer a form of catching up missed triggers (e.g. while the server was offline). To do this, it is necessary to track / log certain executions in the database. To not clutter the database, several levels of CATCHUP mechanisms are provided
/// <summary>
/// The enum describes the behavior what should happen if a schedule or cycle
/// was missed, while the server was offline.
/// </summary>
public enum CATCHUP
{
/// <summary>
/// No History will be added for this schedule
/// </summary>
NONE = 0,
/// <summary>
/// Does nothing when server starts, but keeps a history in the database
/// </summary>
NEVER = 1,
/// <summary>
/// If any number of cycles or schedules were missed, the method will be run ONCE as a catchup
/// </summary>
ONCE = 2,
/// <summary>
/// Performs the schedule / cycle for exactly the amounts of missed cycles or schedules
/// </summary>
ALL = 3
}
Schedule
A Schedule describes the exact point in time a method should be executed / run, using the ScheduleAttribute . It uses the Cronos package to evaluate a given cron-expression.
Each Schedule must return a bool value, indicating if the execution was correctly performed (true) or if an error occured (false).
Tip
As a general advice, even though everything is async and multi-threaded, it is not recommended to have a lot of schedules being triggered at the same time.
Registration
Registering a new schedule is as easy as annotating a certain function with the SCHEDULE attribute.
[Schedule(SCHEDULE.TEST, "0 16 * * *", CATCHUP.ALL)]
public async Task<bool> TestSchedule()
{
_logger.Information("Testing schedule triggered!");
return true;
}
Let's have a look at that.
Schedule Id
The SCHEDULE enum is used for identification, logging and tracking purposes in the database, therefore unique.
Note
The server will not start if a schedule id is present multiple times.
public enum SCHEDULE
{
TEST = 1
}
Cron Format
The cron format in the attribute describes when the schedule should be executed, meaning "0 16 * * *" determines the execution of the function everyday at 16:00
Note
The server will not start if a given cron expression is invalid.
┌───────────── minute
│ ┌───────────── hour
│ │ ┌───────────── day of month
│ │ │ ┌───────────── month
│ │ │ │ ┌───────────── day of week
│ │ │ │ │
* * * * *
Important
The seconds are omitted from the cron expressions
History
Based on the given catchup ALL, the server will check on startup, how often it missed the 16:00 time since the server shutdown.
If a history is tracked, it will be saved as a ScheduleHistory in the database.
Note
If a catchup trigger fails during server start (returning false), the server will not continue to start.
Cycle
A Cycle describes a loose interval with capabilities of history and catchup. All cycles share a single timer to reduce memory footprint. Due to this nature there are some technical limitations.
Note
On server start, if a new cycle is detected, it will start tracking it. If the exact time is required, use a Schedule
Registration
Registering a new cycle is as easy as annotating a certain function with the CYCLE attribute.
[Cycle(CYCLE.TEST, 5, CATCHUP.ALL)]
public async Task<bool> TestCycle()
{
_logger.Information("Testing cycle triggered!");
return true;
}
Cycle Id
The CYCLE enum is used for identification, logging and tracking purposes in the database, therefore unique.
Note
The server will not start if a cycle id is present multiple times.
public enum CYCLE
{
TEST = 1
}
CycleTimer
The cycle timer describes the time in minutes between each trigger. Due to the nature of the cycle, the shortest considerable timespan is 2 minutes.
History
See history section above.
Questions ?
Have any questions or remarks? Feel free to reach out 🙂.
Improvements / TODOs
A list of improvements / todos for the schedules / cycles :
- Add possibility to "silent" a cycle / schedule, so a history is saved, but no logs are triggered