Skip to content

v0.9.0

Compare
Choose a tag to compare
@sergiu128 sergiu128 released this 15 Nov 12:55
· 15 commits to master since this release

What's Changed

Changes related to the correctness of IO:

  • The per async-object stackframe counter dispatched is now in IO. As such, there is one such counter shared between all async-objects sharing an IO.
    • 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 at n * 32 stack frames. If n 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. See TestDispatchLimit in conn_test.go for an example.
      • The counter is now called Dispatched and lives in the IO struct.

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. See fileReadReactor and fileWriteReactor.

Also cleaned up some of the docs.

Full Changelog: v0.8.0...v0.9.0