Flow Control

vielpork provides a complete flow control method to make it easier for you to control the flow when writing asynchronous code.

  • Global control

    • downloader.lock().await.start(resources).await?;
    • downloader.lock().await.pause().await?;
    • downloader.lock().await.resume().await?;
    • downloader.lock().await.cancel().await?;
  • Task control

    • downloader.lock().await.pause_task(resource).await?;
    • downloader.lock().await.resume_task(resource).await?;
    • downloader.lock().await.cancel_task(resource).await?;

Just use it directly in the code, and vielpork will automatically handle the state transitions of the tasks.

State Transition Diagram

stateDiagram-v2
    [*] --> GlobalInit
    GlobalInit --> GlobalRunning: start_all()
    GlobalRunning --> GlobalSuspended: pause_all()
    GlobalSuspended --> GlobalRunning: resume_all()
    GlobalRunning --> GlobalStopped: cancel_all()
    GlobalStopped --> [*]
    
    state TaskStates {
        [*] --> TaskPending
        TaskPending --> TaskDownloading: start_task()
        TaskDownloading --> TaskPaused: pause_task()
        TaskPaused --> TaskDownloading: resume_task()
        TaskDownloading --> TaskCanceled: cancel_task()
        TaskDownloading --> TaskCompleted: finish()
        TaskPaused --> TaskCanceled: cancel_task()
        TaskCanceled --> [*]
        TaskCompleted --> [*]
    }
    
    GlobalSuspended --> TaskPaused : propagate
    GlobalStopped --> TaskCanceled : propagate

Reasonable State Transition

vielpork's state transition is in the form of a finite state machine, with each task having a state, and each task's state transition is finite. This ensures that the task's state transition is reasonable and that unreasonable state transitions do not occur.

Reasonable Global State Transition


#![allow(unused)]
fn main() {
let valid = match (*current, new_state) {
    (DownloaderState::Idle, DownloaderState::Idle) => true,
    (DownloaderState::Idle, DownloaderState::Running) => true,
    (DownloaderState::Running, DownloaderState::Suspended) => true,
    (DownloaderState::Suspended, DownloaderState::Running) => true,
    (DownloaderState::Stopped, DownloaderState::Idle) => true,
    (_, DownloaderState::Stopped) => true,
    _ => false,
};
}

Reasonable Task State Transition


#![allow(unused)]
fn main() {
let valid = match (*current, new_state) {
    (TaskState::Paused, TaskState::Downloading) => true,
    (TaskState::Paused, TaskState::Paused) => true,
    (TaskState::Paused, TaskState::Pending) => true,
    (TaskState::Pending, TaskState::Paused) => true,
    (TaskState::Pending, TaskState::Downloading) => true,
    (TaskState::Downloading, TaskState::Paused) => true,
    (TaskState::Downloading, TaskState::Completed) => true,
    (TaskState::Failed, _) => true,
    (_, TaskState::Failed) => true,
    (_, TaskState::Canceled) => true,
    _ => false,
};
}