Ensuring all pending writes complete before close
"이희승 (Trustin Lee)"
trustin at gmail.com
Tue Aug 11 22:20:11 EDT 2009
Hi Iain,
On 08/06/2009 11:47 PM, Iain McGinniss wrote:
> I have a scenario where two peers are communicating, and once this
> communication comes to the close, the following should happen:
>
> 1. Peer A sends a "quit" message to Peer B.
> 2. Peer A then begins the shutdown sequence (closing open channels,
> releasing thread pools and bootstrap instances, etc).
> 3. Peer A's process exits.
> 4. Peer B, upon receiving the quit message, begins the shutdown
> sequence.
> 5. Peer B's process exits.
>
> The problem I have is that there appears to be a race condition
> between the quit message actually getting across to Peer B and the
> channel being closed - sometimes peer B never receives the quit
> message, and waits endlessly for the quit message. This can be cured
> at a higher level, but I'm trying to see what I can do within the
> channel pipeline to ensure this does not happen.
>
> The strategy I'm about to attempt is to store a set of ChannelFutures
> for all writes requested in my SimpleChannelHandler, in the
> writeRequested() method, and register a listener on these writes. As
> the writes complete, they will be removed from the set of pending
> writes. When a close is requested via the closeRequested() method, I
> do not immediately forward on the close request. Instead, I will set
> an atomic boolean "closing" to true. This will ignore all subsequent
> requests to write to the channel (check inside writeRequested()). Once
> I detect via the listener callback that the pending writes set is
> empty and closing is true, I will send the close request downstream.
>
> I'm hoping the above will have the effect of:
>
> 1. Allowing all pending writes to be completed before I close the
> channel.
You can achieve this pretty simply:
channel.write(ChannelBuffers.EMPTY_BUFFER)
.addListener(ChannelFutureListener.CLOSE);
> 2. Preventing new writes from being requested during shutdown.
This is more tricky. You could maintain a boolean flag as you mentioned
above. An alternative is to write a handler that discards or rejects
any write requests and insert the handler into the pipeline right after
you write an EMPTY_BUFFER.
> 3. Allow for the entity that requested the close to wait for the
> channel to close using the standard mechanism.
I don't follow this. Could you elaborate?
> One issue here could be if the writes never complete, so I suppose I
> will probably need a timeout handler after which I will forward on the
> close request anyway. Does the above sound reasonable, or is there a
> much better way of doing this in Netty?
Yes. Sounds fine to me.
HTH,
Trustin
More information about the netty-users
mailing list