v0.9.0
What's Changed
Changes related to the correctness of IO
:
- The per async-object stackframe counter
dispatched
is now inIO
. As such, there is one such counter shared between all async-objects sharing anIO
.- This counter ensures we don't overflow the stack when multiple async reads/writes can be immediately completed by an async-object. When this happens, we keep building up stackframes by invoking callbacks within callbacks. We limit the stackframe count to
32
by default. Once we hit the limit, even if an async read can be done immediately, we schedule it to be completed asynchronously. This pops all stackframes. - The problem arises when two or more objects build up each other's stackframes. Since the counter is per async object, we can run into a case like the following:
- on each async read, object 1 invokes an async read for object 2
- on each async read, object 2 invokes an async read for object 1
- all reads can be done immediately
- We only pop the stackframes once both objects hit their limit, since the counter is per object. That means we schedule immediate async reads for later only after our stack has grown by 64 frames, even though the limit is 32.
- With
n
objects, we stop atn * 32
stack frames. Ifn
is large, we get a stack overflow - By sharing the counter between all objects, we ensure we never build up more than 32 stackframes, no matter the value of
n
. SeeTestDispatchLimit
inconn_test.go
for an example. - The counter is now called
Dispatched
and lives in theIO
struct.
- This counter ensures we don't overflow the stack when multiple async reads/writes can be immediately completed by an async-object. When this happens, we keep building up stackframes by invoking callbacks within callbacks. We limit the stackframe count to
Performance improvements:
file.go
is alloc-free. That makes all TCP/UDP connections alloc-free. Instead of allocating a read/write handler on each async read/write, we allocate it once at connection init time and ensure we reset the handler's state at the start of each read/write. SeefileReadReactor
andfileWriteReactor
.
Also cleaned up some of the docs.
Full Changelog: v0.8.0...v0.9.0