This commit makes a few changes to the Sink implementation on Framed:
* Backpressure is implemented for `start_send`. If the write buffer is
over 8KiB and can't be flushed, no new items are accepted.
* 0 length writes to the upstream transport are translated into a
`WriteZero` error, as with `io::Write::write_all`. `write_all` checks
for and ignores `Interrupted` errors, but I do not think this is
necessary for non-blocking writes.
* In `poll_complete`, the upstream transport is not flushed until
*after* writing the entire write buffer.
traits into `Codec`
A previous commit refactored such that `Encode` and `Decode` are
implemented directly on the types being encoded or decoded. This was
thought to be less expressive but more convenient than having a separate
notion of a (stateful) encoder or decoder.
However, there are certain situations where the approach is just too
limiting: you're required to implemented `Decode` and `Encode` for types
you don't "own" and can't newtype.
This commit moves back to a setup where `Self` represents the
encoder/decoder state; it also merges the two traits into a single
`Codec` trait, since they are currently always used together.
- Gets rid of `easy` module, instead providing framing support directly
in the `io` module.
- In particular, adds a framing adapter directly to the `Io` trait,
which gives you a Stream + Sink object. That object can then be
`split` into separate `Stream` and `Sink` objects if needed.
- Deprecates the `FramedIo` trait; that's now just Stream + Sink.
- Updates the line framing test to use the stream/sink combinators.
This commit extracts the concrete implementation of `FrameIo` in tokio-proto to
tokio-core under the name `EasyFramed`. This extraction is accompanied with a
new `EasyBuf` buffer type to work with when parsing types.
The purpose of this movement is to provide a clear and easy entry point at the
`FramedIo` layer for those who need it. Eventually these buffer types will get
replaced or moved to the `bytes` crate, but in the interest of an 0.1 release
and remaining backwards compatible with the tokio-core 0.1 release this is
adding a separate module.
The other read futures (read_exact, read_until, etc.) all expose their
concrete future types so that function signatures can return them, but
until now `read()` didn't. Exposing it with the name "Read" causes
naming conflicts with the std::io::Read trait, so the easiest thing to
do is to just change the name. Importing std::io::Read under a different
name would've been an option too, but that would probably be annoying
for consumers in the same way it's annoying for us.
The original PR (https://github.com/tokio-rs/tokio-core/pull/29) decided
that "read" was a better name than "read_some", so I'm leaving the top
level functions unchanged. I don't have a strong opinion about it one
way or the other, but I *do* think it's worth bikeshedding a little bit.
Python's asyncio library actually ended up with a very similar issue
around naming inconsistency between the sync and async worlds, and we
can hopefully avoid repeating that: https://bugs.python.org/issue22279
* Remove `LoopData` as it's no longer necessary
* Add `LoopHandle::spawn` to spawn new futures onto an event loop
* Add `LoopData::spawn` to also spawn new futures onto an event loop
* Rejigger the implementation of the event loop a bit (make a slab of futures),
but otherwise everything else is pretty constant.