Moves `def ack: Event` and `def wantsAck: Boolean` from the `Tcp.WriteCommand` type down to the newly introduced `Tcp.CompactWriteCommand`, which breaks existing code depending on these.
Additionally `Tcp.WriteCommand` now has a few additional methods (`+:`, `++:`, prepend) and a companion object.
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).
Up to now IOExceptions during reading, writing or connecting were treated as
fatal actor errors, crashing the connection actor and thus producing ERROR
level log messages. This patch treats such exceptions as "expected" during
normal operation and prevents them from crashing the actor. Rather, they are
logged at DEBUG level and the actor is actively and cleanly stopped.
* Made defaultDecider available in SupervisorStrategy,
turned out that I didn't need it but I think it could be
good anyway, e.g.
override def supervisorStrategy = OneForOneStrategy(
enableLogging = false)(SupervisorStrategy.defaultDecider)
* Verified the following scenarios:
- client connection failure
- server bind failure
- kill client (peer closed)
- kill server (peer closed)
- also make a Write’s “ack” be a Tcp.Event (to suit pipelines)
- add stress test for BackpressureBuffer
- add it to SslTlsSupportSpec
- add it to the docs
- remove TcpPipelineHandler’s type parameter
- remove not-accept() failure test (which is completely bogus)
- add comments explaining more about TcpPipelineHandler.Init
- remove the funny “manager” from the Server example
This doesn't change any test logic, it merely structures the test fixture code a bit differently to make it easier to insert additional mocks required for coming additions.
also included:
- a complete rewrite of the TCP docs based on real/tested/working code
samples
- an EchoServer implementation which handles all the edge cases,
available in Java & Scala
- renamed StopReading to SuspendReading to match up with ResumeReading
- addition of Inbox.watch()
- Inbox RST docs for Java(!) and Scala
not included:
- ScalaDoc / JavaDoc for all IO stuff
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.
Before, a Tcp.ErrorClosed event is generated when a connection attempt fails. For symmetry with the Tcp.Bind case and general usability of the API a Tcp.CommandFailed(connect) is the better choice.
For these reasons:
- pipeline effect will allow to start processing on the first part of the
data immediately in parallel
- data in `Received` messages is now always a simple ByteStrings which will
improve iteration speed in the next layer
- code becomes simpler