tokio-rs/axum

WebSocket::try_recv

Opened this issue · 4 comments

Feature Request

Motivation

WebSocket::recv blocks the runtime, causing it to wait for a new message. Consequently, when I share Arc<Mutex<WebSocket>> between threads, all threads are blocked until the client sends a message, which would release the block temporarily by triggering a new loop iteration.

Proposal

I propose implementing WebSocket::try_recv, which would give instant feedback, whether there is a message received from client or not.

Alternatives

I have no idea how to solve this problem alternatively.

The alternative to using Arc<Mutext<Ws>> is to use an actor pattern, where you spawn a task that takes full ownership of the resource (websocket connection) and communicate with that resource via message passing.

Arc<Mutex<_>> is typically used for data.

The axum websocket example follows this pattern.

Thank you!
Should I close this issue or proposal of creating WebSocket::try_recv will be considered?

I don't know much about websockets but try_recv sounds sensible.

I skimmed over tokio-tungstenite::WebSocketStream and it doesn't seem to be exposing anything that'd allow for implementation of try_recv (other than the alternative further down, but I don't know if that'd be appropriate). I agree with the @Michael-J-Ward that storing websocket or any kind of async io inside mutex is an anti-pattern, but alternative way of checking if a message is available immediately could be usage of https://docs.rs/futures/latest/futures/future/trait.FutureExt.html#method.now_or_never