=act #3602 report Connected only when connection attempt was successful

Before this change, a client connection was always instantly reported as
`Connected`, even if the endpoint would never respond at all.

The reason is a weird behavior of OP_CONNECT and SocketChannel in the
JDK (observed in Linux):
 - a channel is always connectable before the connection is attempted
   (`channel.connect`). Selecting for OP_CONNECT before the `connect`
   call will instantly report connectable
 - even worse: after OP_CONNECT was reported true, also `finishConnect`
   will always return true, even if the connection wasn't yet established.
   That's probably the case because `finishConnect` is internally implemented
   depending on previous epoll results (on Linux).
This commit is contained in:
Johannes Rudolph 2013-09-12 11:28:45 +02:00
parent 9456a081b7
commit 1a67e937c7
3 changed files with 17 additions and 4 deletions

View file

@ -138,6 +138,7 @@ class TcpConnectionSpec extends AkkaSpec("""
serverSideChannel.write(ByteBuffer.wrap("immediatedata".getBytes("ASCII")))
serverSideChannel.configureBlocking(false)
interestCallReceiver.expectMsg(OP_CONNECT)
selector.send(connectionActor, ChannelConnectable)
userHandler.expectMsg(Connected(serverAddress, clientSideChannel.socket.getLocalSocketAddress.asInstanceOf[InetSocketAddress]))
@ -762,7 +763,7 @@ class TcpConnectionSpec extends AkkaSpec("""
lazy val clientSideChannel = connectionActor.underlyingActor.channel
override def run(body: Unit): Unit = super.run {
registerCallReceiver.expectMsg(Registration(clientSideChannel, OP_CONNECT))
registerCallReceiver.expectMsg(Registration(clientSideChannel, 0))
registerCallReceiver.sender must be(connectionActor)
body
}
@ -784,6 +785,7 @@ class TcpConnectionSpec extends AkkaSpec("""
serverSideChannel.configureBlocking(false)
serverSideChannel must not be (null)
interestCallReceiver.expectMsg(OP_CONNECT)
selector.send(connectionActor, ChannelConnectable)
userHandler.expectMsg(Connected(serverAddress, clientSideChannel.socket.getLocalSocketAddress.asInstanceOf[InetSocketAddress]))