-
Notifications
You must be signed in to change notification settings - Fork 223
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Half-blocking method. Is it supported/possible? #271
Comments
It is not recommended to use If by "half-blocking" you mean writing messages to Websocket from sync world and reading from it from async (e.g. Tokio) world (or the same with reading and writing swapped), then you should use You should specify you use case (how such "half-blocking" Websockets intergrate into a larger scheme) for a more specific advice. |
My scheme is following:
So the only approach is non-blocking single-thread C-like manner. That what I call half-blocking mode. So it's:
My point is that reading is problematic here. Perhaps same issue in tungstenite might be useful here snapview/tungstenite-rs#308 |
What thread will wait for socket events?
What happens after such flagging? How will the application know when to attempt reading from the websocket next time?
Note that if you Rust server (or network between the client and the server) is slow then that socket write gets length - backpressure. |
It's the same single thread only available.
It's done by timer. So it's poor man's polling.
Yes. That's unfortunate, but I cannot see any other viable alternative. |
OK, so we are in the hacks land. In this case I would still use async/nonblocking everywhere (including for sending) by rolling customized low-level async utils (socket wrapper, timers) and maybe executor (though This way the only tradeoffs I expect are:
Other than that, from outside the plugin should look as if socket were used directly, without any additional file descriptors, threads and so on. Here is my demo using It should handle backpressure properly. Maybe there are ready-made crates for such use case, but sometimes it is simpler to write than to find. |
That's a real gift (not gist) :) |
Hi again. I'm not that experienced in async Rust, so it looks like "subtask1" & "subtask2" are doing async send/receive. Thus a question - how can I "drive" them synchronously? I mean - should I build an intermediate queue between sync & async code to pass values when sending/receiving from host application? Making use of something like following does not seem to be right as the "main loop" is hidden behind let send_fut = c_tx.send(Message::Text(format!("Hello, {}", 1))); //.await;
block_on(send_fut)?; |
What do you mean "to drive synchronously"? If you want to interact with sync code, you'll probably need a channel like For driving subtasks simultaneously Here is my second demo that shows some of the ideas above applied: https://gist.github.com/vi/39607d1963b069a5167099f3fbffebf4
|
Yes. I'd like send/receive values to/from async part into/from sync functions.
Thanks a lot for details. So, I guess the right way to emulate "non-blocking receive" is to read channel after doing following. Right? self.wakers.wake_all();
self.exe.run_until_stalled(); |
Yes, using Note that if you want to do more tricky things (timeouts, retries, reconnects, simultaneous things) while staying single-threaded&nonblocking then you may prefer doing them within async world and only deliver final result to sync when needed. |
Yes. I guess it looks possible now with your help. |
Hi
I am trying to implement "half-blocking" mode.
That is blocking write & non-blocking read.
Currently I use following code together with tungstenite. Blocking write is done using "write_inner". TcpStream is from "mio" crate.
Unfortunately, it does not work reliably.
I am getting various errors at handshake & later time.
I'd like to ask. If rust-websocket could be used to implement working scheme like that?
The text was updated successfully, but these errors were encountered: