-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Fix file data streaming for http polling #14659
Conversation
@tsmaeder I'm not sure this is fixable by "fixing" the polling implementation - polling is by design multiplexed (we always have one polling connection and 0 or more request connections open at a time). Therefore, we would need to fix the backend service to not accidentally send the data before responding from the handler. In fact, it shouldn't require to respond at all. |
911b81d
to
f78257f
Compare
@tsmaeder I've changed the code so that the race condition observed in the initial post is no longer possible. The frontend is now in charge of the file handle instead of receiving the file handle from the backend. |
@msujew maybe I'm misunderstanding the issue, but if I do this in the back end (pseudocode):
I expect the front end to receive the reply before the event. Otherwise we'll run into trouble in various places. Is there a reason the polling implementaton of socket.io should work differently than the websocket implemention in this case? |
@tsmaeder I've read up on this a bit socket.io guarantees message ordering on both websocket and http fallback. I would generally assume that this works as intended. However, what we've been doing is a bit of a hack anyway: We attempt to respond with a handler id, that we already use in the events, without making any guarantees about the order. This doesn't seem to be a problem in websocket contexts, but likely due to some specific implementation details. I see no reason why this also shouldn't fail on websockets. To explain this in pseudo code: const response = await service.do(() => {
frontEnd.sendEvent(someEvent);
});
frontEnd.sendReply(response); On websockets, The new implementation fixes this issue by specifiying the handler on the frontend level, something that is way cleaner anyway and something that we do throughout the rest of the codebase as well. |
Ah, I get it:
Just wanted to make sure we don't overlook some deeper problem here. |
The only difference I can see for polling is that websocket probably uses some native event mechanism, whereas the polling likely goes through a timeout. That might reorder the execution releative to promises. |
@msujew trying to reproduce this with the transport fixed to 'polling', but opening files from the explorer works just fine for me without the fix 🤷 |
Never mind, I was able to reproduce to for some files in the browser version. |
What it does
Closes #14067
When using socket.io's long polling mechanism, sending messages to the frontend in the backend while responding to a request from the frontend might result in messages arriving in an unexpected order. In particular, it might result in those notifications arriving before the request response arrives.
Usually this is no issue, since we rarely depend on the exact order of messages. However, in the file data streaming, we expect the response before any of the notifications arrive. This seems to be the case with websockets, but not with long polling.
This change makes the frontend in charge of the sequence id handle instead of the backend. This entirely removes the possibility of a race condition without impacting the behavior of the file streaming feature.
How to test
Follow-ups
We might want to look into any potential other places where we depend on notifications + a response for a backend RPC call. I don't think there are any others, but I wouldn't guarantee it.
Review checklist
Reminder for reviewers