lf-lang / reactor-rs

Reactor runtime implementation in Rust
MIT License
9 stars 5 forks source link

Removal of scoped threads for physical actions #34

Closed oowekyala closed 1 year ago

oowekyala commented 2 years ago

Summary

Rationale

The LF-Rust runtime currently forces the user to use [[scoped threads]] if they want to create a thread that can communicate with the schedule. The reason it is so is to be able to capture references to the internals of the scheduler. It's not a good reason because it could actually be avoided, although it's the historical reason.

There is one debatably good thing that this design gives us, it's that those async threads are guaranteed to be joined by the scheduler when it shuts down the program. I think it's nice because it gives strong semantics to the [[shutdown]] procedure, but it's also maybe not the semantics that we want - maybe it's convenient to let those async threads die alone when the scheduler shuts down.

Using scoped threads actually is otherwise very cumbersome. We have to carry around [[lifetime annotations]] everywhere in the scheduler, which is a source of great pain. It also prevents users from storing threads in reactors and joining them whenever they require it (because otherwise reactors would have to carry lifetime annotations themselves - my attempt at allowing that didn't go well). For instance a program like AsyncCallback cannot be implemented. Ultimately it doesn't net the user more flexibility because the scope of the thread is fixed and only allows taking references to scheduler internals, which LF users don't have access to. It's only an implementation artefact that gets exposed to the user through the interface.