7 ms·
Indeed. On a semi-related note, any thoughts on how you could merge Async with non-Async code? Eg, I've got a large codebase that is not threaded but not Async
by asdkhadsj 7y ago
Indeed.
On a semi-related note, any thoughts on how you could merge Async with non-Async code? Eg, I've got a large codebase that is not threaded but not Async. In the future, I might upgrade the web server to be Async and slowly start porting code.
I had planned/hoped that I could make my own Async/Thread bridge.
Such that non-Async code would live in it's own thread, and I would make a special Future ask a Mutex in another thread if data is available. Taking special care not to lock the Future's thread.
The goal of course is to not have to rewrite the entire app's blocking code at once.
Does this sound stupid to you?
- nicoburns 7y agoYou probably want channels. There's an implementation in the standard library: https://doc.rust-lang.org/std/sync/mpsc/ https://doc.rust-lang.org/std/sync/mpsc/ Or a faster/more ergonomic one in the crossbeam-channel library: https://docs.rs/crossbeam-channel/0.4.0/crossbeam_channel/ https://docs.rs/crossbeam-channel/0.4.0/crossbeam_channel/
- asdkhadsj 7y agoI've used them a ton in Go, and a tiny bit in Rust. I would think channels could fail here though - for the same reason that a Mutex could fail, no? Channels can block a thread if you wait for data. You could of course have a channel that you simply use in a non-blocking fashion, asking if data is ready. You could also implement similar behavior in a Mutex. However, I do think you're right, a channel would likely fit this paradigm better; and with less chance of accidentally blocking the executor/future thread. Appreciate the feedback, thanks!
- kd5bjo 7y agoYou should be able to come up with something. Fundamentally, the role of the executor is to be the bridge between sync and async code: it isn't async itself but is responsible for making all the async code move forward. No async code will do anything when the executor isn't active. The way I split up the game code, raw event handling and rendering was written as a standard, synchronous, game loop. The game logic update was written with async code, and once per frame, I call the executor which keeps control until none of the async tasks can make further progress. You can probably do something similar in your case: find somewhere in the existing program where it isn't disruptive to do arbitrary work, and have the executor do its work there.