mdeloof / statig

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

Allow async functions as state handler or actions #3

Closed coder3101 closed 1 year ago

coder3101 commented 1 year ago

It is a well documented and clean library on HSM. I would have used it in my next project but my use case demands to perform async operations inside state handler and possibly in actions.

It would be nice to have a crate feature to enable async support for such use cases. By default, it can be off.

mdeloof commented 1 year ago

Hi, thanks for taking a look at statig. Async event handlers and actions are definitely something I want to support at one point, but I think this will require async trait methods which are still unstable as of now. The async-trait crate could be a possible solution in the meantime but there are a couple of other things that I want to add first so I'll see where things stand by then.

matthewgapp commented 1 year ago

@mdeloof thanks so much for this amazing crate. Huge plus one for this ask. My use case involves a lot of async which I'm handling now by passing messages to an async runtime. I'd love for a first-class way to handle async side effects.

mdeloof commented 1 year ago

Thanks!

I've been working on it and have an implementation that runs on nightly using the async_fn_in_trait feature. The only problem that I've encountered is that statig uses recursion to walk the transition path and doing recursion with async functions requires the returned futures to be allocated on the heap (so inside a Box<T>), which means async wouldn't be supported on no-std. Now I think I might eventually be able to solve this because the maximum recersion depth can be known at compile time and so I could statically allocate enough space to store the futures, but I still need to look into it. In the meantime I might just require std for async support. Would that match your use case? If so I could use the same workaround as the async-trait crate and bring it to stable already along with the 0.3 update.

sadilekivan commented 1 year ago

@mdeloof I just recently stumbled across this crate and love the idea. I also use async code, but I don't know which would be better, if to use the nightly async feature or async-trait. Thus far I used async-trait to stay on the safe side so I would definitely appreciate the feature!

mdeloof commented 1 year ago

Added in 5b910ce.

I went with the async-trait solution for now. Async on no-std would be nice eventually but I'm going to have to give it some more thought. Hopefully the current implementation can already cover most of the use cases people had. Happy to help if you encounter any issues!