#状态机 #步骤函数 #任务编排

sfn-machine

使用链表实现的任务编排和链式操作的状态机,以保证在需要不同流程时的一致性和灵活性。

3 个版本

0.1.3 2023 年 12 月 28 日
0.1.1 2023 年 12 月 24 日
0.1.0 2023 年 12 月 24 日

866解析器实现

每月 下载 25

MIT/Apache

25KB
270

state-machine

Rust 中惯用的状态机实现。

此软件包提供了一个简单的 Rust 状态机惯用实现。此软件包提供的状态机与 AWS 状态机定义风格紧密相似。该软件包仍在开发中,并将随着可用性的增加发布更多功能。

状态机由以下状态的步骤组成

仍在积极开发中,主分支将是最稳定的副本

pub enum State {
    Task,
    Choice(fn() -> bool),
    Sleep(u64),
    Pass,
    Parallel,
    Succeed,
    Fail,
    Map,
    CustomState,
}

以下是一个简单使用示例

use std::{error::Error, fmt::Debug};
use serde::{Deserialize, Serialize};
use sfn_machine::machine::
    {state::{StateMachine, State}, data::DeserializeStateData};

// Define the struct representing the shared data
#[derive(Debug, Serialize, Deserialize)]
struct SharedData {
  counter: i16,
  id: String,
}

// Implement the deserialization trait for the SharedData struct
impl DeserializeStateData for SharedData {
  fn from_json(json: &str) -> Result<Self, Box<dyn Error>> {
    let data: Self = serde_json::from_str(json)?;
    Ok(data)
  }
}

fn match_vecs<T: PartialEq + std::fmt::Debug>(a: &Vec<T>, b: &Vec<T>) -> bool {
    let mut matching = true;
    for index in 0..a.len() {
        if !b.contains(&a[index]) {
            matching = false;
            break
        }
    };

    matching
}

pub fn main() {
    // JSON representation of the shared data
    let json_data = r#"{"counter": 5, "id": "come-id"}"#;
    // Deserialize the shared data
    let shared_data: SharedData = SharedData::from_json(json_data).expect("Failed to deserialize data");

    // Define state functions
    fn state_function_a(data: &mut SharedData) -> Result<(), Box<dyn Error>> {
      data.counter += 1;
      Ok(())
    }

    fn state_function_b(data: &mut SharedData) -> Result<(), Box<dyn Error>> {
      data.counter += 100;
      Ok(())
    }

    fn state_function_c(data: &mut SharedData) -> Result<(), Box<dyn Error>> {
      data.counter *= 1;
      Ok(())
    }

    fn state_function_d(data: &mut SharedData) -> Result<(), Box<dyn Error>> {
        data.counter *= 5;
        Ok(())
    }

    // Create a state machine
    let mut shared_data = SharedData { counter: shared_data.counter, id: shared_data.id };
    let mut sfn_machine = StateMachine::new("MachineA011".to_string(), &mut shared_data, 3);

    sfn_machine.step("NodeA", State::Task, state_function_a, None, None, None, None);
    sfn_machine.step("NodeB", State::Task, state_function_b, None, None, None, None);
    sfn_machine.step("NodeC", State::Task, state_function_c, None, None, None, None);
    // The end attribute can be set optionally. When set, the node becomes the last step in the state machine
    sfn_machine.step("NodeD", State::Task, state_function_d, None, None, None, Some(true));

    // Validate node IDs
    sfn_machine.validate_node_ids();

    // execute state machine
    if let Err(err) = sfn_machine.execute() {
      println!("State machine execution failed: {}", err);
    }
  }

概述

实现作为链表实现,这意味着执行将遵循定义的顺序,无需额外工作即可按给定顺序执行。

还可以使用步骤函数的 next 属性定义执行顺序。

fn state_function_a(data: &mut SharedData) -> Result<(), Box<dyn Error>> {
  data.counter += 1;
  Ok(())
}

fn state_function_b(data: &mut SharedData) -> Result<(), Box<dyn Error>> {
  data.counter += 100;
  Ok(())
}

let mut shared_data = SharedData { counter: shared_data.counter, id: shared_data.id };
let mut sfn_machine = StateMachine::new("MachineA011".to_string(), &mut shared_data, 3);

sfn_machine.step("NodeA", State::Task, state_function_a, state_function_b, None, None, None);
sfn_machine.step("NodeB", State::Task, state_function_b, None, None, None, None);

同样,也可以定义状态机的最后一步。

还可以定义一组错误来捕获或重试,并在匹配时采取相应的行动。示例

sfn_machine.step("Node0", State::Task, StateMachine::error, None, None, Some(vec!["STATE.FAILED"]), Some(false));

依赖项

~0.7–1.6MB
~35K SLoC