trio icon indicating copy to clipboard operation
trio copied to clipboard

zmq support

Open njsmith opened this issue 8 years ago • 9 comments

Everyone seemed really excited about this in curio, and it should be pretty simple, so hey, why not.

References:

  • curio implementation: https://github.com/dabeaz/curio/blob/master/examples/curio_zmq.py
  • some notes on how to avoid ZMQSelector: https://forum.dabeaz.com/t/adventures-in-adding-zeromq-support/156/6?u=njsmith
  • aiozmq now has a proper non-ZMQSelector-based implementation; worth looking at

This should go into a standalone package though – triozmq, not trio.zmq.

njsmith avatar Apr 11 '17 05:04 njsmith

Hi. What is the current status of this issue? It seems that ZMQSelector is not needed anymore in newer versions of pyzmq. And curio's zmq example is now quite simple. Can zmq be supported in trio through the same way?

kawing-chiu avatar Sep 14 '18 09:09 kawing-chiu

Getting zmq to play nicely with regular event loops is pretty non-trivial. (That's why pyzmq used to try to dodge the issue by providing a custom loop.) We can do it though, it's just not trivial. See https://github.com/python-trio/trzmq and its readme for details of what needs to happen.

The change in pyzmq.asyncio is just that they finally did the non-trivial work described in that readme.

That curio example is just wrong AFAICT, because it completely misunderstands how the zmq waiting interface works. I guess Dave never tested it under load. If send ever blocks, it will deadlock, and recv will get stuck too under some circumstances.

njsmith avatar Sep 14 '18 14:09 njsmith

Hi, it's any plan to support nanomsg?

jiangrzh avatar Nov 09 '18 01:11 jiangrzh

@jiangrzh I'm not very familiar with nanomsg, but will happily cheer you on if you want to get it working with Trio :-). Do you use the older nanomsg or the newer nng? Is there a Python wrapper already that you like?

njsmith avatar Nov 09 '18 03:11 njsmith

@njsmith Thank you for your response. I'm new to trio and nanomsg too. I think nng is better than nanomsg, but it seens python wrapper for nng is no ready for production?

jiangrzh avatar Nov 09 '18 07:11 jiangrzh

@jiangrzh we've had brief discussion over at @codypiersall's new pynng. Sounds like @gdamore is interested in easing the pains of this integration in nng itself as well :+1:

goodboy avatar Nov 09 '18 07:11 goodboy

@njsmith I've read the notes on trzmq but can't say I understand it fully, since I have little knowledge on zeromq/trio internals.

As far as I understand it, the major problem is how to tame the "edge-triggered" behavior of the zmq FD. I've found a post on how to integrate zmq with the libev eventloop, not sure whether this approach is feasible for trio?

Another thing I found is that zeromq has a new poller api which is level-triggered. It is still a draft api but may become stable sometime later. And here is pyzmq's author asking about whether this new poller api can be used to integrate with other eventloops.

kawing-chiu avatar Nov 10 '18 12:11 kawing-chiu

@kawing-chiu Thanks for the links! I think we do know how to integrate zmq with the trio event loop. It's just a bit complicated, so it will take a bit of work for someone to wrap their head around it, write the code, test and document it, etc. I haven't had time to do that, and even if I did then I probably wouldn't have time to focus on maintaining it well. Someone who actually uses zmq themselves would probably do a better job of that :-).

AFAICT from that poller API doc, currently it's just a more efficient version of zmq_poll, which doesn't help us – we need something fundamentally different than zmq_poll. Reading the discussion in the issue you linked (https://github.com/zeromq/libzmq/issues/2941), it does sound like there's some tentative plan to change this in the future, but it doesn't sound like anyone is actually working on it currently, so... fingers crossed I guess!

njsmith avatar Nov 14 '18 08:11 njsmith

Just to follow up to @jiangrzh, we do have support for async operations on nng sockets in pynng. It couldn't have been done without help from @njsmith, @tgoodlet, and @gdamore! (Disclaimer: I'm the creator of pynng!)

Example usage:

import pynng
import trio

async def send_and_recv(sender, receiver, message):
    await sender.asend(message)
    return await receiver.arecv()

with pynng.Pair0(listen='tcp://127.0.0.1:54321') as s1, \
        pynng.Pair0(dial='tcp://127.0.0.1:54321') as s2:
    received = trio.run(send_and_recv, s1, s2, b'hello there old pal!')
    assert received == b'hello there old pal!'

The library is still a work in progress (what libraries aren't?). It can be installed via pip.

codypiersall avatar Jan 17 '19 16:01 codypiersall