Odd timing of channelConnected(), Netty 3.1.0beta2

Trustin Lee tlee at redhat.com
Mon May 25 15:18:16 EDT 2009


Hi Ian,

IIUC, you are getting the ClosedChannelException at NioWorker.cleanUpWriteBuffer() on the client side and you are sending a message and close the connection immediately, right?  It's normal that Channel.isConnected() can return false even in channelConnected() if the connection has been closed very quickly.  Channel might have been connected at the point where the channelConnected event is fired, but not at the point where the handler is actually executed.

If so, do you call Channel.close() *after* the ChannelFuture returned by Channel.write() is set as 'done'?  If not, you have a high chance of getting such a race condition because Channel.write() in Netty never blocks in NIO transport.

Usually, the following idiom is used to make sure Channel.close() is called after last write request is sent:

    // Close the connection when writing the last message finishes.
    ch.write(lastMessage).addListener(ChannelFutureListener.CLOSE);

HTH,
Trustin

On Mon, 25 May 2009 02:54:53 +0900, IanS <iswett at yahoo.com> wrote:

>
> I'm having an odd situation where commonly I am getting a  
> channelConnected()
> event after I get a channelDisconnected() event for the same channel.
>
> Additionally, it initially says it is connected(which it isn't), but in  
> the
> code below, the warn does not typically occur, but it hits the println  
> and
> says that isConnected()=false somewhat commonly, so the value if
> isConnected() is changing during channelConnected() method.
>
> Since it is a client channel I'm initiating, missing out on the initial
> channelConnected() is not as bad as getting a random channelConnected()  
> call
> later, after channelDisconnected().
>
>
> An example log is:
>
> 2009-05-24 00:40:56,370: [id: 0x0018849c] OPEN
> creating client channel [id: 0x0018849c] with address=10.0.1.177:8087
> 2009-05-24 00:40:56,371: [id: 0x0018849c, /10.0.1.177:51696 =>
> /10.0.1.177:8087] BOUND: /10.0.1.177:51696
> 2009-05-24 00:40:56,371: [id: 0x0018849c, /10.0.1.177:51696 =>
> /10.0.1.177:8087] CONNECTED: /10.0.1.177:8087
> 2009-05-24 00:40:56,372: [id: 0x0018849c] DISCONNECTED
> channelDisconnected([id: 0x0018849c])
>
> .....
>
> 2009-05-24 10:46:56,153: Unexpected exception from downstream for
> channel=[id: 0x0018849c]
> java.nio.channels.ClosedChannelException
> 	at
> org.jboss.netty.channel.socket.nio.NioWorker.cleanUpWriteBuffer(NioWorker.java:536)
> 	at  
> org.jboss.netty.channel.socket.nio.NioWorker.close(NioWorker.java:518)
> 	at
> org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink.eventSunk(NioClientSocketPipelineSink.java:97)
> 	at
> org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream(OneToOneEncoder.java:66)
> 	at
> org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream(OneToOneEncoder.java:66)
> 	at org.jboss.netty.channel.Channels.close(Channels.java:1043)
> 	at  
> org.jboss.netty.channel.AbstractChannel.close(AbstractChannel.java:185)
> 	at
> org.jboss.netty.channel.group.DefaultChannelGroup.close(DefaultChannelGroup.java:185)
>
> .....
>
> channelConnected: adding channel [id: 0x0018849c] with
> address=10.0.1.177:8084 isConnected()=false
>
>
>
> I believe I am creating this situation by opening a channel, sending a
> message, then shutting down immediately.  I will likely need to wait for  
> my
> message to get sent in the future, but this is still a possible and  
> fairly
> reproducible situation.
>
>
> Here is my code for channelConnected() and the getHostString() it calls:
>
>
>      public void channelConnected(ChannelHandlerContext ctx,
> ChannelStateEvent e) throws Exception
>      {
> 	    	// Not sure if this call is necessary.
> 	    	super.channelConnected(ctx, e);
> 	    	
> 	    	Channel channel = e.getChannel();
> 	    	
> 	    	if(!channel.isConnected())
> 	    	{
> 	    		logger.warn("channelConnected: Supplied with a disconnected  
> channel =
> "+channel);
> 	    		return;
> 	    	}
> 	    		
> 	    	String address = getHostString(channel);
> 	    	
> 	    	System.out.println("channelConnected: adding channel "+channel+"  
> with
> address="+address+" isConnected()="+channel.isConnected());
> 	    	channelAddresses.put(channel, address);
> 	    	openChannels.put(address, channel);
> 	    	allChannels.add(channel);
>         }
>
> 	public static String getHostString(Channel channel)
> 	{
> 		SocketAddress remoteAddress = channel.getRemoteAddress();
> 		if(remoteAddress==null)
> 			return null;
> 		String address = remoteAddress.toString();
> 		if((remoteAddress instanceof InetSocketAddress))
> 			address = ((InetSocketAddress)
> remoteAddress).getHostName()+":"+((InetSocketAddress)
> remoteAddress).getPort();
> 		if(address.charAt(0)=='/')
> 			address = address.substring(1);
> 		
> 		return address;
> 	}


-- 
- Trustin Lee, http://gleamynode.net/



More information about the netty-users mailing list