Implement InputStream.nonBlockingReads and document it

This commit is contained in:
Zahary Karadjov 2020-05-06 23:54:28 +03:00
commit ec5c3af313
No known key found for this signature in database
GPG key ID: C8936F8A3073D609
3 changed files with 56 additions and 0 deletions

View file

@ -317,6 +317,35 @@ proc performHandshake(c: Connection): bool {.async.} =
It is assumed that in traditional async code, timeouts will be managed more
explicitly with `sleepAsync` and the `or` operator defined over futures.
#### Non-blocking reads
Protocols transmitting serialized payloads often provide information regarding
the size of the payload. When you invoke the deserialization routine, it's
preferable if the provided boundaries are treated like an "end of file" marker
for the deserializer. FastStreams provides an easy way to achieve this without
extra copies and memory allocations through the `nonBlockingReads` facility.
Here is a typical usage:
```nim
proc decodeFrame(s: AsyncInputStream, DecodedType: type): Option[DecodedType] =
if not s.readable(4):
return
let lengthPrefix = toInt32 s.read(4)
if s.readable(lengthPrefix):
s.nonBlockingReads(lengthPrefix):
s.readValue(Json, DecodedType)
```
Please note that the above example uses the [nim-serialization library](https://github.com/status-im/nim-serialization/)
Simply, inside the `nonBlockingReads` block, `s.readable` will return `false`
as soon as the Json parser has consumed the specified number of bytes.
Furthermore, it's guaranteed that no blocking operations are possible and
thus our `AsyncInputStream` will be treated like a normal `InputStream`.
Depending on the complexity of the stream processors, this will often lead
to much more optimal code.
### `OutputStream` and `AsyncOutputStream`
An `OutputStream` manages a particular output device. The library offers out