io: handle half-closed connection when peer closed first
This allows to send data back to the peer even if the peer already has sent EOF/FIN as specified for TCP. To fully close a connection, the handler has to close its side of the connection now actively once it is finished with writing even if it received a `PeerClosed` message before.
This commit is contained in:
parent
632c310e9a
commit
1b95f65cf4
3 changed files with 77 additions and 23 deletions
|
|
@ -389,6 +389,39 @@ class TcpConnectionSpec extends AkkaSpec("akka.io.tcp.register-timeout = 500ms")
|
|||
|
||||
selector.send(connectionActor, ChannelReadable)
|
||||
connectionHandler.expectMsg(PeerClosed)
|
||||
connectionHandler.send(connectionActor, Close)
|
||||
|
||||
assertThisConnectionActorTerminated()
|
||||
}
|
||||
"report when peer closed the connection but allow further writes and acknowledge normal close" in withEstablishedConnection() { setup ⇒
|
||||
import setup._
|
||||
|
||||
closeServerSideAndWaitForClientReadable(fullClose = false) // send EOF (fin) from the server side
|
||||
|
||||
selector.send(connectionActor, ChannelReadable)
|
||||
connectionHandler.expectMsg(PeerClosed)
|
||||
object Ack
|
||||
connectionHandler.send(connectionActor, writeCmd(Ack))
|
||||
pullFromServerSide(TestSize)
|
||||
connectionHandler.expectMsg(Ack)
|
||||
connectionHandler.send(connectionActor, Close)
|
||||
connectionHandler.expectMsg(Closed)
|
||||
|
||||
assertThisConnectionActorTerminated()
|
||||
}
|
||||
"report when peer closed the connection but allow further writes and acknowledge confirmed close" in withEstablishedConnection() { setup ⇒
|
||||
import setup._
|
||||
|
||||
closeServerSideAndWaitForClientReadable(fullClose = false) // send EOF (fin) from the server side
|
||||
|
||||
selector.send(connectionActor, ChannelReadable)
|
||||
connectionHandler.expectMsg(PeerClosed)
|
||||
object Ack
|
||||
connectionHandler.send(connectionActor, writeCmd(Ack))
|
||||
pullFromServerSide(TestSize)
|
||||
connectionHandler.expectMsg(Ack)
|
||||
connectionHandler.send(connectionActor, ConfirmedClose)
|
||||
connectionHandler.expectMsg(ConfirmedClosed)
|
||||
|
||||
assertThisConnectionActorTerminated()
|
||||
}
|
||||
|
|
@ -535,8 +568,8 @@ class TcpConnectionSpec extends AkkaSpec("akka.io.tcp.register-timeout = 500ms")
|
|||
val clientSelectionKey = registerChannel(clientSideChannel, "client")
|
||||
val serverSelectionKey = registerChannel(serverSideChannel, "server")
|
||||
|
||||
def closeServerSideAndWaitForClientReadable(): Unit = {
|
||||
serverSideChannel.close()
|
||||
def closeServerSideAndWaitForClientReadable(fullClose: Boolean = true): Unit = {
|
||||
if (fullClose) serverSideChannel.close() else serverSideChannel.socket.shutdownOutput()
|
||||
checkFor(clientSelectionKey, SelectionKey.OP_READ, 3.seconds.toMillis.toInt) must be(true)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue