Struct sacs::scheduler::Scheduler

source ·
pub struct Scheduler { /* private fields */ }
Expand description

The main work horse of SACS. Provides everything needed to run and control Tasks.

§Overview

Scheduler runs as independent Tokio task (so you don’t need to pool it using await/select/join), and it’s responsible on:

  • provisioning new and removing existing tasks on request
  • starting jobs according to the task’s schedule
  • collecting and providing task’s status
  • clean scheduler’s state from orphaned task’s data
  • shutdown

Scheduler uses some kind of it’s own “executor” engine under the hood to start jobs on Tokio runtime with respect to provided constrains: runtime type, number of threads and parallelism (maximum number of simultaneously running jobs).

New scheduler can be created using convenient SchedulerBuilder or using Scheduler::default() method or using long version of the trivial constructor Scheduler::new()

Each Scheduler has at least three configuration parameters:

  • WorkerType - type of Tokio runtime to use for workload: CurrentRuntime, CurrentThread or MultiThread
  • WorkerParallelism - limits number of simultaneously running jobs, or makes it unlimited
  • GarbageCollector - provide way to clean statuses of orphaned tasks to avoid uncontrolled memory consumption

You can use reasonable default parameters for trivial schedulers or provide yours own (via builder or constructor) to tune behavior according to your needs. You can run as many schedulers as you need with different configurations.

§Examples

The simplest config using default constructor:

  • use current Tokio runtime
  • limit workers to 16 jobs
  • without garbage collector
use sacs::{Result, scheduler::{Scheduler, ShutdownOpts, TaskScheduler}};

#[tokio::main]
async fn default_scheduler() -> Result<()> {
    let scheduler = Scheduler::default();
    // ...
    scheduler.shutdown(ShutdownOpts::IgnoreRunning).await
}

Use separate MultiThread Tokio runtime, collect finished tasks immediately:

use sacs::{
    scheduler::{RuntimeThreads, Scheduler, SchedulerBuilder, GarbageCollector,
                ShutdownOpts, TaskScheduler, WorkerType},
    Result,
};

#[tokio::main]
async fn multi_thread_scheduler() -> Result<()> {
    let scheduler = SchedulerBuilder::new()
        .worker_type(WorkerType::MultiThread(RuntimeThreads::CpuCores))
        .garbage_collector(GarbageCollector::Immediate)
        .build();
    // ...
    scheduler.shutdown(ShutdownOpts::WaitForFinish).await
}

Use separate MultiThread Tokio runtime with:

  • 4 threads
  • unlimited number of jobs
  • garbage collector with 12 hours expiration time, run it every 15 minutes
use sacs::{
    scheduler::{GarbageCollector, RuntimeThreads, Scheduler, SchedulerBuilder,
                ShutdownOpts, TaskScheduler, WorkerParallelism, WorkerType},
    Result,
};
use std::time::Duration;

#[tokio::main]
async fn specific_scheduler() -> Result<()> {
    let scheduler = SchedulerBuilder::new()
        .worker_type(WorkerType::MultiThread(RuntimeThreads::Limited(4)))
        .parallelism(WorkerParallelism::Unlimited)
        .garbage_collector(GarbageCollector::periodic(
            Duration::from_secs(12 * 60 * 60), // expire after
            Duration::from_secs(15 * 60),      // interval
        ))
        .build();
    // ...
    scheduler
        .shutdown(ShutdownOpts::WaitFor(Duration::from_secs(60)))
        .await
}

Implementations§

source§

impl Scheduler

source

pub fn new( worker_type: WorkerType, parallelism: WorkerParallelism, garbage_collector: GarbageCollector ) -> Self

Basic Scheduler constructor. Using of SchedulerBuilder is another way to construct it with custom parameters.

Trait Implementations§

source§

impl Default for Scheduler

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl TaskScheduler for Scheduler

source§

async fn add(&self, task: Task) -> Result<TaskId>

Post new Task to scheduler.

Right after that task will be staring to execute according to it’s schedule.

Returns TaskId of the scheduled task or Error::DuplicatedTaskId if task with the same TaskId is already present, even if it’s finished but not removed by getting it’s status or by garbage collector.

source§

async fn cancel(&self, id: TaskId, opts: CancelOpts) -> Result<()>

Removes Task with specified TaskId from the scheduler with respect to CancelOpts: task can be killed or left to continue working up to finish.

Returns Error::IncorrectTaskId if task is not scheduled or cleaned by garbage collector.

source§

async fn status(&self, id: &TaskId) -> Result<TaskStatus>

Returns current status of the task.

If task is finished then it’s status will be removed from the scheduler after this method call, so following calls with te same TaskId will fail with Error::IncorrectTaskId.

source§

async fn shutdown(self, opts: ShutdownOpts) -> Result<()>

Starts process of scheduler shutdown:

  • remove awaiting tasks from the queue
  • shuts down executing engine with respect to ShutdownOpts.

Can return Error::IncompleteShutdown in case of errors.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

source§

fn vzip(self) -> V

source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more