Asyncdispatch hard fork
Core differences between asyncdispatch and asyncdispatch2
-
Unified callback type
CallbackFunc:Current version of asyncdispatch uses many types of callbacks:
proc ()is used in callSoon() callbacks and Future[T] completion callbacks.proc (fut: Future[T])is used in Future[T] completion callbacks.proc (fd: AsyncFD, bytesTransferred: Dword, errcode: OSErrorCode)is used in Windows IO completion callbacks.proc (fd: AsyncFD): boolis used in Unix IO event callbacks.
Such a large number of different types creates big problems in the storage and processing of callbacks and in interaction between callbacks. Lack of ability to pass custom user data to a callback also creates difficulties and inefficiency with passing custom, user-defined data needed for using closures (one more allocation).
To resolve this issue, we have introduced a unified callback type,
CallbackFunc:type CallbackFunc* = proc (arg: pointer = nil) {.gcsafe.}Also, one more type was introduced for the callback storage,
AsyncCallback:type AsyncCallback* = object function*: CallbackFunc udata*: pointer -
The order of Future[T] completion callbacks:
Current version of asyncdispatch processes Future[T] completion callbacks in reverse order, but asyncdispatch2 schedules callbacks in forward order: https://github.com/nim-lang/Nim/issues/7197
-
Changed the behavior of OS descriptor event callbacks:
For some unknown reason, the current version of asyncdispatch uses seq[T] to hold a list of descriptor event listeners. However, in the asynchronous environment, there is no need for a list of event listeners. In asyncdispatch2, there is only one place for one READ listener and one place for one WRITE listener.
-
Removed the default timeout value for the poll() procedure, which allows incorrect usage of asyncdispatch and produces 500-ms timeouts in correct usage.
-
Changed the behavior of the scheduler in the poll() procedure, and fixed the following issues:
-
Asyncdispatch2 no longer uses
epochTime(); instead, it uses the fastest time primitives for a specific OS,fastEpochTime(). Also, because MacOS supports only a millisecond resolution inkqueue, sub-millisecond resolution is not needed. For details, see https://github.com/nim-lang/Nim/issues/3909. -
Removed all IO primitives (
recv(),recvFrom(),connect(),accept(),send(), andsendTo()) from the public API, and moved all their functionality into Transports. -
Introduced an
addTimer()/removeTimer()callback interface. -
Introduced
removeReader()foraddReader()andremoveWriter()foraddWriter(). -
Changed the behavior of the
addReader(),addWriter(), andaddTimer()callbacks. Now, only the explicit removal of the callbacks must be supplied viaremoveReader(),removeWriter(), andremoveTimer(). -
Added the support for the cross-platform
sendfile()operation. -
Removed the expensive
AsyncEventand the support for hardware timers andaddProcess.addProcesswill be implemented as SubprocessTransport, while hardware-basedAsyncEventwill be renamed toThreadAsyncEvent. -
Added cheap synchronization primitives:
AsyncLock,AsyncEvent, andAsyncQueue[T].
Documentation
You can find more documentation, notes and examples in [Wiki].
Installation
You can use Nim official package manager nimble to install asyncdispatch2. The most recent version of the library can be installed via:
$ nimble install https://github.com/status-im/nim-asyncdispatch2
License
Licensed under one of the following:
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license: LICENSE-MIT or http://opensource.org/licenses/MIT
TODO
- Pipe/Subprocess Transports.
- Multithreading Stream/Datagram servers
- Future[T] cancelation