Communicating between sync and async code

I've got a piece of compute-heavy synchronous code and I'd like to let users control it via a web UI that talks to a web server. Most of the web server frameworks I've been looking at are built on top of hyper and use asynchronous IO.

Are there any established conventions for sending messages from my async web server to my sync code?

I was looking at futures::channel::mpsc and noticed Receiver::try_next() can be called without needing Pin or a waker... Is it okay to use send/receive on a futures channel outside of a Future? Or is this liable to accidentally deadlock or panic?

Yes, all futures types should work anywhere the type system allows them, they make no assumptions about any kind of global state. (The one exception I know of is block_on specifically will panic if called recursively, because blocking inside a Future is such a big no-no). So you can use Receiver::try_next periodically to poll if there is a value available, and block_on(Receiver::next) if you want to block in synchronous code waiting for a message from async code; and vice-versa with Sender::try_send and block_on(Sender::send).

2 Likes

Channels are indeed the preferred way to communicate between sync and async code. You should use the kind of channel such that the receiver matches, e.g. blocking channels when the receiver is in sync code.

1 Like