NeatPeriodicTaskScheduler constructor

NeatPeriodicTaskScheduler({
  1. required String name,
  2. required Duration interval,
  3. required Duration timeout,
  4. required NeatPeriodicTask task,
  5. NeatStatusProvider? status,
  6. Duration minCycle = const Duration(minutes: 5),
  7. Duration maxCycle = const Duration(hours: 3),
})

Create a NeatPeriodicTaskScheduler.

The name is used when writing log messages, notably it is written as '### [ALIVE] neat-periodic-task: "<name>"', when the task is verified to have been completed within interval time from now. Thus, monitoring logs and alerting if this message does not appear at-least every 3 * interval is a very robust way to alert about task failure.

The interval is the time interval with which the task should be invoked. A new task will not be started until the previous task has finished, unless this takes longer than timeout.

If the system has multiple processes running the same task, a NeatStatusProvider can be used to synchronize task scheduling through a status file. Notice that the NeatStatusProvider interface is stateful, thus, it is always wrong to reuse an instance of NeatStatusProvider.

The status provider is effectively a light weight locking mechanism to prevent the task from running concurrently. However, this only holds if the task always completes or fails within timeout, as it may otherwise be restarted.

If the task fails consistently, it will be retried at timeout delay, this will continue indefinitely. Thus, it is sensible to pick a high timeout, if the operation is expensive and this can be tolerated.

Implementation

NeatPeriodicTaskScheduler({
  required String name,
  required Duration interval,
  required Duration timeout,
  required NeatPeriodicTask task,
  NeatStatusProvider? status,
  Duration minCycle = const Duration(minutes: 5),
  Duration maxCycle = const Duration(hours: 3),
})  : _name = name,
      _interval = interval,
      _timeout = timeout,
      _task = task,
      _statusProvider = status ?? _InMemoryNeatStatusProvider(),
      _minCycle = minCycle,
      _maxCycle = maxCycle {
  if (maxCycle <= minCycle) {
    throw ArgumentError.value(
        maxCycle, 'maxCycle', 'maxCycle must larger than minCycle');
  }
  if (interval < minCycle * 2) {
    throw ArgumentError.value(interval, 'interval',
        'interval must be large than 2 * minCycle for reasonable behavior');
  }
}