Skip to content

picanumber/task_timetable

Repository files navigation

C++ chrono-scheduler

Defer tasks for execution or repetition at specified intervals.

Project Status: Active – The project has reached a stable, usable state and is being actively developed. license

CI Memory Threading CodeQL Style

Usage

The library is tested on linux, macOs and windows.

Scheduler

Schedulers are instances of the CallScheduler class, which resides in the ttt (task time table) namespace:

#include "scheduler.h"

{
    bool compensate = true; // Whether to calculate the time point of task
                            // executions by adding the interval to the:
                            // true: task start / false: task finish.

    unsigned nWorkers = 1;  // Number of workers that run tasks.

    ttt::CallScheduler plan(compensate, nWorkers);
}

Adding a task to the scheduler is done using its add method:

{
    auto myTask = []{
        ttt::Result ret{ ttt::Result::Repeat };

        if ( /*user logic*/ )
        {
            ret = ttt::Result::Finish;
        }

        return ret; // A user task returns whether to repeat or not.
    };

    auto token = plan.add(
        myTask, // User tasks are std::function<ttt::Result()>
        500ms,  // Interval for execution or repetition
        false); // Whether to immediately queue the task for execution
}

As shown above, the addition of a task returns a token marked [[no_discard]]. Tokens control the behavior of the associated task:

  1. The token is alive => Task is allowed to run.
  2. The token is destroyed => Tasks are prevented from running after token destruction and are removed from the scheduler.
  3. The token is detached => Task is independent from the token state.

To detach a token from its task, call the detach() method. If there is no need to ever cancel a task, e.g. it dies with the scheduler, the following syntax can be used to ignore the token upon creation:

plan.add(myTask, 500ms, false).detach();
// user task ^^  ^^     ^^     ^^^^^^ Dissociate the token from task execution.
//      interval ^^     ^^
// schedule immediately ^^

Users that don't want to use scopes and object lifetimes to control the execution of a task, i.e. let the destructor of token cancel the task, can wrap tokens in std::optional and explicitly trigger the cancellation of a task:

auto token = std::optional(plan.add(myTask, 500ms, false));
//
// Let the task run for a desired amount of time.
//
token.reset(); // Triggers the token's destructor which cancels task execution.

Timeline

The timeline class is a container of chrono-restricted tasks. Different flavors of tasks that can be defined include:

  • Timers : repeatable with stateful countdown
  • Pulses : repeatable with period state
  • Alarms : one-off task with interval state e.g. a deferred notification.

Usage is documented in the respective header (timeline.h), but essentially each task type has methods to be added, removed, stopped and so on, as seen in the following example.

ttt::Timeline schedule;

std::string const name("timer1");
schedule.timerAdd(
    name,                     // Timer name.     
    100ms,                    // Resolution (frequency of timer ticks)
    1s,                       // Duration - what we count down from
    false,                    // Countdown again, after running a duration cycle
    [](TimerState const& s) { // Invoked on every resolution step
        std::cout << s.remaining.count() << "ms out of " << s.duration.count() << "ms\n"; 
    },
    true // Trigger the timer upon addition - Callback invoked with remaining=duration
);

auto serializedState = schedule.serialize(true, true, true);
// what to serialize, i.e.          timers^  pulses^  ^alarms

ttt::Timeline tl2(serializedState); // Recreation of a timeline from serialized state.

Building

Build by making a build directory (i.e. build/), run cmake in that dir, and then use make to build the desired target.

Example:

> mkdir build && cd build
> cmake .. -DCMAKE_BUILD_TYPE=[Debug | Coverage | Release]
> make
> ./main
> make test      # Makes and runs the tests.
> make coverage  # Generate a coverage report.
> make doc       # Generate html documentation.

A convenience script rebuild_all.sh is provided for users that want to generate all types of build, i.e. release, sanitizers (thread & address) and debug.

About

C++ library to execute or repeat user provided tasks at specified intervals.

Resources

License

Stars

Watchers

Forks

Packages

No packages published