Details
-
Bug
-
Status: Resolved
-
Normal
-
Resolution: Fixed
Description
StreamSession#prepareAsync() executes, as the name implies, asynchronously from the IO thread: this opens up for race conditions between the sending of the PrepareSynAckMessage and the call to StreamSession#maybeCompleted(). I.e., the following could happen:
1) Node A sends PrepareSynAckMessage from the prepareAsync() thread.
2) Node B receives it and starts streaming.
3) Node A receives the streamed file and sends ReceivedMessage.
4) At this point, if this was the only file to stream, both nodes are ready to close the session via maybeCompleted(), but:
a) Node A will call it twice from both the IO thread and the thread at #1, closing the session and its channels.
b) Node B will attempt to send a CompleteMessage, but will fail because the session has been closed in the meantime.
There are other subtle variations of the pattern above, depending on the order of concurrently sent/received messages.
I believe the best fix would be to modify the message exchange so that:
1) Only the "follower" is allowed to send the CompleteMessage.
2) Only the "initiator" is allowed to close the session and its channels after receiving the CompleteMessage.
By doing so, the message exchange logic would be easier to reason about, which is overall a win anyway.
Attachments
Issue Links
- links to