Repository navigation
Conversation
…onnect packet fails
Merging this PR will not alter performance
|
62b326c to
0047482
Compare
|
Hey, thanks for your contribution. I'd like to solve your problem with a more idiomatic solution, IMO running disconnect handler whereas the socket is not yet connected is not the appropriate solution. I agree that we should make an /// # Wait for the underlying engine.io connection to be closed.
///
/// Resolves when the client disconnects or the server closes the transport.
/// Inside a connect middleware, this lets slow work (an auth lookup, say)
/// be abandoned as soon as the client leaves.
pub async fn closed(&self) {
self.esocket.closed().await
}You could then use it like that: async |s: SocketRef| {
tokio::select! {
res = auth_lookup(&s) => res,
_ = s.closed() => Err(AuthError::ClientGone),
}
}About your issue, what are the reason for handling of your bookkeeping in the middleware rather than in the connect handler, is it because it needs to run before connection or is it because you want composability? |
Agreed on On the bookkeeping: it has to run before the connection, composability is not the reason. The connect handler is not a safe place for it because of this window in The socket is inserted into Once the disconnect handler lives in the middleware, the only path where it is skipped is the failed connect packet, which is what the Thanks! |
Why
A connect middleware that does slow work (an auth lookup, for example) cannot tell whether the client is still there when the work finishes:
Socket::connected()is false for every socket until after the connect packet, and the engine socket is private. So the middleware accepts a client that already left.Also, when the client drops right before the connect packet is sent,
Namespace::connectremoves the socket directly and no disconnect handler runs, so bookkeeping a middleware set up (a connection counter, for example) is never undone.What
Socket::is_closed(): passthrough to the engine socket, meaningful inside a middleware.Namespace::connect: on a failed connect packet, close the socket throughSocket::closewithTransportErrorso disconnect handlers run, instead ofremove_socket.Tests
Two integration tests in
tests/connect.rson the websocket fixture:is_closed()flips to true after the client drops mid-middleware, and the disconnect handler fires withTransportErrorwhen the client drops before the connect packet (fails without thens.rschange).