mdeloof / statig

Hierarchical state machines for designing event-driven systems
https://crates.io/crates/statig
MIT License
560 stars 18 forks source link

Using multiple async state machines in parallel #12

Closed sadilekivan closed 1 year ago

sadilekivan commented 1 year ago

I'm having trouble making multiple simple async state machines run in tokio::spawn tasks since it requires the Send trait and I don't think I can resolve this inside my crate. I recently saw a commit on cleaning up some trait bounds so I'm unsure if the async HSM have statig::Response<rescources::State> not Send on purpose and I should deal with this on my side.

Am I using a wrong approach to try and create multiple state machines and manage them in some larger state machine? Or should I just make one larger with lots of superstates. I find that having multiple would be nice to independently test how simpler state machines react to their events.

If needed I can supply a minimal reproducible main.rs, for now here is the cargo build error I get:

note: future is not `Send` as this value is used across an await
   --> /home/ivan/.cargo/git/checkouts/statig-9f81b8df0f2647e3/19da112/statig/src/inner.rs:69:13
    |
67  | /         self.state
68  | |             .enter(&mut self.shared_storage, context, enter_levels)
    | |___________________________________________________________________- has type `std::pin::Pin<Box<dyn Future<Output = ()>>>` which is not `Send`
69  |               .await;
    |               ^^^^^^- the value is later dropped here
    |               |
    |               await occurs here, with the value maybe used later
note: required by a bound in `tokio::spawn`
    |
163 |         T: Future + Send + 'static,
    |                     ^^^^ required by this bound in `spawn`

error: future cannot be sent between threads safely
   --> src/rescources/prepare.rs:29:17
    |
29  |                 async move { material_magazine.unload().await },
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
    |
    = help: the trait `Send` is not implemented for `dyn Future<Output = statig::Response<rescources::State>>`
note: required by a bound in `tokio::spawn`
   --> /home/ivan/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/spawn.rs:163:21
    |
163 |         T: Future + Send + 'static,
    |                     ^^^^ required by this bound in `spawn`

warning: `millimess-1003` (bin "millimess-1003") generated 6 warnings
error: could not compile `millimess-1003` due to 2 previous errors; 6 warnings emitted
mdeloof commented 1 year ago

Yeah my bad, I was probably a bit too eager in removing those trait bounds. I've re-added them with 43b6419.

mdeloof commented 1 year ago

I've added an async example where a task is spawned with Tokio and some async I/O is done. Everything looked good so I'll close this issue. Please let me know if you face any other issues :).