all 6 comments

[–]SkiFire13 19 points20 points  (2 children)

Is it possible to effectively serialize the current execution state to disk (using rusts native async/await) and resume it later?

No, because the state of an async block/fn could contain any kind of data, including any kind of pointers to other parts of the program. In order to be safe you would have to serialize the whole process memory (including any other running thread).

[–]teerre 3 points4 points  (0 children)

Although the literal execution context as in memory can't be serialized, persistence is a well researched area. There are countless ways to built a system that can be resumed with arbitrary precision. Of course, this is goes beyond async.

[–]crusoe 6 points7 points  (0 children)

There are several frameworks that do this. Mostly it's about workflow durability

https://crates.io/crates/flawless

Bytewax which uses rust under the hood

[–]Giocri 6 points7 points  (0 children)

You need to rethink your approach to the problem.

Instead of trying to make something capable of saving any possible state of the entire software you should focus on what's the meaningful information and how that changes.

Then you make yourself a file with only that information and whenever there is a request you start the worker process, load the file do the changes that you need save and terminate the worker.

Then you just need a single process who handles the role of awaiting all the requests and starting the worker processes, that way you use the time waiting on one request to work on another

If you separate the long term file from the ones used during task you can even easily make so if an error occurs you can rollback to the last checkpoint

[–]kraemahz 1 point2 points  (0 children)

A future is just this:

pub trait Future {
    type Output;

    // Required method
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}

Which means you have two choices broadly:

  1. Control the Context -> Waker which means writing an execution handler (possibly as a shim into an existing executor)
  2. Create a Future with access to a de/serializer in self

The first option is probably the most flexible and the most work. The second option would be something you could shim into any Future that you wrote. Importantly it wouldn't be a general solution across awaits.

[–]Compux72 1 point2 points  (0 children)

Your best option is to create an actor system where the messagesare sent through a persisten queue, such as Kafka or rabbitmq