title: Akka connection abort
body: <p>I have strange behavior with Akka TCP IO, the problem is connection reset, due to explicit call of <code>TcpMessage.abort()</code> from handler or <code>Terminating</code> handler. Peer did not receive <code>Tcp.ConnectionClosed</code> event. Example:</p>
  
  <p>Handler onReceive</p>
  
  <pre><code>@Override
  public void onReceive(Object msg) throws Exception {
      if (msg instanceof Tcp.ConnectionClosed) {
          log.info("Server ConnectionClosed: {}", msg);
          getContext().stop(getSelf());
      } else if (msg instanceof Tcp.Received){
          log.info("Aborting connection");
          getSender().tell(TcpMessage.abort(), getSelf());
      }
  }
  </code></pre>
  
  <p>Test code</p>
  
  <pre><code>new JavaTestKit(system) {{
       getSystem().actorOf(Props.create(Server.class, getRef()), "Server");
       Tcp.Bound bound = expectMsgClass(Tcp.Bound.class);
  
       ActorRef client = getSystem().actorOf(
       Props.create(Client.class, bound.localAddress(), getRef()), "Client");
       watch(client);
       expectMsgClass(Tcp.Connected.class);
       client.tell(new Message.Write(), getRef());
  
       expectTerminated(client);
  }};
  </code></pre>
  
  <p>Log after execution</p>
  
  <pre><code>[INFO] [10/19/2013 22:13:22.730] [actorSystem-akka.actor.default-dispatcher-3] [akka://actorSystem/user/Client] Client Connected
  [INFO] [10/19/2013 22:13:22.736] [actorSystem-akka.actor.default-dispatcher-3] [akka://actorSystem/user/Client] Sending Write to Handler
  [INFO] [10/19/2013 22:13:22.767] [actorSystem-akka.actor.default-dispatcher-3] [akka://actorSystem/user/Server/$a] Aborting connection
  [INFO] [10/19/2013 22:13:22.774] [actorSystem-akka.actor.default-dispatcher-3] [akka://actorSystem/user/Server/$a] Server ConnectionClosed: Aborted
  
  java.lang.AssertionError: assertion failed: timeout (3 seconds) during expectMsg: Terminated Actor[akka://actorSystem/user/Client#423174850]
  </code></pre>
  
  <p>If i change <code>TcpMessage.abort()</code> to <code>TcpMessage.close()</code> in handler:</p>
  
  <pre><code>[INFO] [10/19/2013 22:17:06.243] [actorSystem-akka.actor.default-dispatcher-4] [akka://actorSystem/user/Client] Client Connected
  [INFO] [10/19/2013 22:17:06.249] [actorSystem-akka.actor.default-dispatcher-4] [akka://actorSystem/user/Client] Sending Write to Handler
  [INFO] [10/19/2013 22:17:06.278] [actorSystem-akka.actor.default-dispatcher-4] [akka://actorSystem/user/Server/$a] Aborting connection
  [INFO] [10/19/2013 22:17:06.288] [actorSystem-akka.actor.default-dispatcher-6] [akka://actorSystem/user/Client] Client ConnectionClosed: PeerClosed
  [INFO] [10/19/2013 22:17:06.288] [actorSystem-akka.actor.default-dispatcher-3] [akka://actorSystem/user/Server/$a] Server ConnectionClosed: Closed
  </code></pre>
  
  <p>How server handler can signal remote client what connection is error closed? Everything works fine if i send abort from client to server.</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>Ok, found root of problem, Abort command not working only if i sent Write command before i try to abort. On both client and server. Now i need figure out why.</p>
  
  <p><strong>EDIT2:</strong></p>
  
  <p>Seems like abort message is getting stuck, if i create new client then <code>ErrorClosed</code> is reached first client, and sending same write command to second client execute abort which received by client as expected.</p>
  
  <pre><code>new JavaTestKit(system) {{
      getSystem().actorOf(Props.create(Server.class, getRef()), "Server");
      Tcp.Bound bound = expectMsgClass(Tcp.Bound.class);
  
      ActorRef client = getSystem().actorOf(
              Props.create(Client.class, bound.localAddress(), getRef()), "Client");
      watch(client);
      expectMsgClass(Tcp.Connected.class);
      client.tell(new Message.Write(), getRef());
      expectNoMsg();
  
      ActorRef client2 = getSystem().actorOf(
             Props.create(Client.class, bound.localAddress(), getRef()), "Client2");
      watch(client2);
      expectMsgClass(Tcp.Connected.class);
  
      expectTerminated(client);
  
      client2.tell(new Message.Write(), getRef());
  
      expectTerminated(client2);
      expectNoMsg();
  }};
  </code></pre>
  
  <p>And log:</p>
  
  <pre><code>[INFO] [10/20/2013 00:48:05.923] [actorSystem-akka.actor.default-dispatcher-4] [akka://actorSystem/user/Client] Client Connected
  [INFO] [10/20/2013 00:48:05.929] [actorSystem-akka.actor.default-dispatcher-4] [akka://actorSystem/user/Client] Sending Write to Handler
  [INFO] [10/20/2013 00:48:05.959] [actorSystem-akka.actor.default-dispatcher-4] [akka://actorSystem/user/Server/$a] Aborting connection, connection actor: [Actor[akka://actorSystem/system/IO-TCP/selectors/$a/2#1767183113]]
  [INFO] [10/20/2013 00:48:05.966] [actorSystem-akka.actor.default-dispatcher-6] [akka://actorSystem/user/Server/$a] Server ConnectionClosed: Aborted
  [INFO] [10/20/2013 00:48:08.930] [actorSystem-akka.actor.default-dispatcher-6] [akka://actorSystem/user/Client2] Client Connected
  [INFO] [10/20/2013 00:48:08.934] [actorSystem-akka.actor.default-dispatcher-3] [akka://actorSystem/user/Client] Client ConnectionClosed: ErrorClosed(An existing connection was forcibly closed by the remote host)
  [INFO] [10/20/2013 00:48:08.936] [actorSystem-akka.actor.default-dispatcher-4] [akka://actorSystem/user/Client2] Sending Write to Handler
  [INFO] [10/20/2013 00:48:08.937] [actorSystem-akka.actor.default-dispatcher-4] [akka://actorSystem/user/Server/$b] Aborting connection, connection actor: [Actor[akka://actorSystem/system/IO-TCP/selectors/$a/4#-598138943]]
  [INFO] [10/20/2013 00:48:08.938] [actorSystem-akka.actor.default-dispatcher-4] [akka://actorSystem/user/Server/$b] Server ConnectionClosed: Aborted
  [INFO] [10/20/2013 00:48:08.938] [actorSystem-akka.actor.default-dispatcher-7] [akka://actorSystem/user/Client2] Client ConnectionClosed: ErrorClosed(An existing connection was forcibly closed by the remote host)
  </code></pre>
  
  <p><strong>EDIT3:</strong></p>
  
  <p>To make it a little bit more clear, question is: How i can inform my remote actor handler what peer is crashed and <code>ErrorClosed</code> the connection (it doing it on remote end). Last <code>ErrorClosed</code> message is always being stuck, it did not disappear, it just sits somewhere in selector and only pushed to peer after i do another network operation (write or connect another actor to the server). This behavior only encountered if i do <code>Write</code> command before aborting. This behavior is OS independent; i tried on Windows and Linux machine, same result.</p>