-
Notifications
You must be signed in to change notification settings - Fork 145
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
Add WebSocket::inner method #337
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why expose inner instead of adding a buffered_amount
method?
@@ -199,6 +199,11 @@ impl WebSocket { | |||
}) | |||
} | |||
|
|||
/// Provides a reference to the JS `WebSocket` instance wrapped by this struct. | |||
pub fn inner(&self) -> &web_sys::WebSocket { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be into_inner
and consume self
.
That would defeat the whole point of this PR: if I had a way to turn a raw websocket back into a gloo websocket, then I could just create the WS myself, clone the reference, and then pass that to gloo.
While buffered_amount would suffice for my particular use case, direct access to the underlying JS websocket reference is generally convenient for cases where gloo’s API is not sufficient. Furthermore, it does not look like any memory safety invariants can be broken with access to the inner reference. And if I intentionally break gloo by e.g. overriding the onmessage handler, then that’s obviously on me. |
The API should prevent you from being able to make such a mistake |
You’re not going to be able to prevent someone from monkeypatching the WebSocket constructor 🤷♂️ As I said: buffered_amount alone would be sufficient for my personal use case. But as things are right now, if I have a use case that isn’t directly served by gloo’s API then I am effectively forced to fall back to raw Websockets entirely, and that is obviously substantially more error-prone than having a small escape hatch. Btw, the reason I need buffered_amount is to provide backpressure. One might argue that gloo should implement backpressure (since it’s not intuitive for a Sink to drop messages on the floor just because it’s overwhelmed), so that’s yet another option, albeit one that requires a significant amount of code and introduces a subtle change in behavior. |
I am also in favour of a consumption-based API
The same argument can be raised to say that you can use LLDB to modify the memory and violate compile time safety put in place by Rust compiler. Because something that is not possible to completely prevent from happening doesn't mean that any effort put towards it to provide a better sound API is not worth it. On the topic of providing back pressure, I do not think there is a good way of doing it unless WebSocket provides events to help monitoring the watermarks (Such as events to signal buffer level) so we can wake up sink based on it.
I don't think JavaScript's WebSocket implementation will drop messages just because it is back logged as well? I think the buffer in WebSocket is unbound and can grow indefinitely. (Until an unknown limit set by the browser is reached.) |
By the same reasoning, it should not be possible to write My point is that a hypothetical bad-faith user of your API will always be able to break things, no matter how hard you try. If I want my code to erroneously not receive websocket messages, then I don't have to resort to e.g. overriding gloo's
There is unfortunately no elegant way to do it, but a polling-based approach (as outlined by e.g. the Chrome developers here) using For a general-purpose offering like
You are correct: the spec does not provide a backpressure mechanism, so the limit is implementation-dependent. Quoting MDN:
Exceeding the send buffer is punished by killing the connection and silently dropping all subsequently sent data on the floor. |
A way to take care of this would be to have into_raw and from_raw methods, similar to Box. I'm not sure if I want to make the latter I would still prefer to add whatever methods are needed to WebSocket to provide the data that the underlying instance provides. If anything other than bufferedAmount, I'd be happy to add that as well |
This is useful to call e.g.
buffered_amount
.