I have just released version 0.3.0 of collections.nim and reactor.nim libraries!

reactor.nim is an alternative asynchronous networking engine for Nim based on libuv. The main addition in this release is much improved documentation (Github, tutorial, API docs).

collections.nim is a collection of several mostly independent module (Github, API docs). Notably, is has weakref module that implements weak references and pprint which is a more readable alternative to built-in repr.

2017-01-10 20:06:05

I looked into your collections library, and I saw your View library. I have my own implementation of the same thing here. Maybe it has minor differences, but generally it is the same thing. openArray in parameters also serves almost the same thing. I would really like to see the DataView library to be part of the standard library.

I saw that you have View and ConstView. Parameters are by default not mutable and only when the var keyword is prepended they are mutable. I think you should follow the same pattern here and use VarView and View, const is so c++.

2017-01-10 23:31:40

Does reactor support any kind of compatibility with the standard async?

In particular, there is the module asynchttpserver: how hard would it be to port it to reactor?

As a second question: what, if any, is the interaction between reactor event loop and threading? Would it be possible to build an actually multithreaded http server on top of reactor? (with different threads servicing different connections, each of them async)?

2017-01-11 10:47:21

There is no direct compatiblity with standard async, but porting code from stdlib should be easy (many features have similar syntax).

Currently there is support for running tasks in a thread pool, but the tasks can't use event loop at all (https://networkos.net/nim/reactor.nim/doc/api/reactor/threading.html). I'm planning for quite a long time to add multithreaded HTTP server to reactor.nim, libuv already supports passing sockets between threads.

2017-01-11 11:07:36
Thank you! Right now Rosencrantz is based on the stdlib HTTP server, but I have been wanting to base it on something multithreaded for a while
2017-01-11 11:28:05

I really appreciate your efforts but I must ask, why did you decide to write a new library instead of helping improve the standard lib async modules?

My fear is that we will end up with 30% of libraries supporting reactor.nim, 40% of libraries supporting stdlib async and 30% supporting async future project foobar. What can we do to avoid this?

2017-01-11 12:39:09
I started this project with the following assumptions:
  • use libuv (or something similar) to avoid having to support code for every platform (this is really important, I don't want to test everything on >3 platforms even when making small changes)
  • have API as clean as possible.

I don't thing you and Araq would accept rewriting asyncdispatch to use libuv and dramatically changing the API of asyncdispatch/asyncnet. Future and Input/Output objects are incompatible with stdlib for good reasons - for example, using my abstractions, it's possible to:

  • efficiently implement readLine without using internals of socket object
  • do async calls without allocations in a more elegant way than FutureVar
  • write SSL/TLS support module without inlining it into module that supports sockets (!)

To avoid the situation you described, I'm planning to write drop-in asyncdispatch/asyncnet replacement that will use reactor.nim loop. In the long run, I think the way to go is to define portable API for event loops (in a same way Python does). This way, different async libraries could be bridged together.

2017-01-11 13:34:15

@dom96

By the way, I think event-driven models are useful for plug-in programming. How about adding events to asyncdispath and asynchttpserver? Such as :

proc handleError(err: SomeError) {.async.} =
  await sleepAsync(1000)
  echo "handleError"

proc handleRequest(req: Request) {.async.} =
  await sleepAsync(1000)
  while true:
    var chunk = await req.readStream.recv()
    if chunk == "":
      break
    echo "recv a chunk: " & chunk

server.on("clientError", handleError)
server.on("request", handleRequest)

2017-01-11 13:42:51
Some minor issues:
  • Links in the docs to the source code don't work.
  • Shouldn't .asynciterator be just .async and the macro check if it got an nnkProcDef or nnkIteratorDef?
2017-01-12 12:40:01