On Sat, Dec 30, 2017 at 12:00 AM, Luca Boccassi <[email protected]>
wrote:

> On Fri, 2017-12-29 at 22:32 +0100, Pavol wrote:
> > Hello,
> >
> > I'm trying to get udpping3 example
> > <http://zguide.zeromq.org/page:all#Designing-the-API> from ØMQ Guide
> > working. Originally I tried GitHub issue tracker (#715
> > <https://github.com/booksbyus/zguide/issues/715>) and Kevin Sapper
> > advised
> > to ask on a mailing list. Feel free to head there for more verbose
> > context.
> >
> > With the current code (udpping3.py, udplib.py and interface.py) I get
> > ZMQError: Socket operation on non-socket. I *guess* this happens
> > because
> > InterfaceAgent thread closes pipe first and later Interface tries to
> > close
> > pipe as well. If I remove that self.pipe.close() from InterfaceAgent
> > I
> > don't get error mentioned above anymore.
> >
> > With this modified example I end up with different issue. Main
> > Interface
> > class hangs on context termination. I've read Making a Clean Exit
> > <http://zguide.zeromq.org/page:all#Making-a-Clean-Exit> part of the
> > guide.
> > I don't see suggested linger setting on a socket so I hoped python
> > bindings
> > does that somehow.
> >
> > I'm wondering if example doesn't exit properly or what could be the
> > issue?
> >
> >
> > For more details feel free to peek in the issue on GitHub:
> > https://github.com/booksbyus/zguide/issues/715
>
> After a quick glance there are a couple of race conditions in that
> example - one of the socket is created in thread 0, used in thread 1
> and then closed in thread 0. Sockets are not thread safe. That might,
> or might not, be the issue.
>

Thanks for pointing this out. Only after this I've realized that self.pipe
in InterfaceAgent is actually self.p1 in Interface and it is different from
self.pipe in Interface which is actually self.p0.

So I've caused that hang of context termination with closing one part of
the pipe.

I've moved that other pipe close to main thread where it was created. But
that still wasn't enough.

I've managed to make the code working in the end. Relevant part of the
Interface class:

    def __init__(self):
        self.ctx = zmq.Context()
        p0, p1 = pipe(self.ctx)
        self.agent = InterfaceAgent(self.ctx, p1)
        self.agent_thread = Thread(target=self.agent.start)
        self.agent_thread.start()
        self.pipe = p0
        self._agent_pipe = p1 # save Agent side of the pipe for later use

    def stop(self):
        self.agent.stop() # request agent thread to stop
        self.agent_thread.join() # wait until loop.start() in agent
finishes so no more pooling on pipe is done
        self.pipe.close() # close Interface side of the pipe
        self._agent_pipe.close() # close Agent side of the pipe
        self.ctx.term()

With this code I haven't seen any stuck termination nor socket errors
anymore. I'll send PR soon.



>
> I would suggest to focus on the bigger picture with these examples -
> see what capabilities, features and network patterns are possible and
> how to implement them, at a higher level. Implementation details like
> perfectly handling ctrl-c are besides the point.
>

What I found so far (https://stackoverflow.com/a/37012803) UDP isn't as
well supported by zmq as TCP. It seems python example of Radio/Dish (
https://github.com/zeromq/pyzmq/tree/master/examples/draft) is still in
draft support ( http://pyzmq.readthedocs.io/en/latest/draft.html ).

So I wanted to give it a try with existing examples. And it turned out that
reliability of the code (example?) wasn't as nice as it could be. I wasn't
sure in which part (zmq? pyzmq? examples?) was the issue.

Anyway I fully agree looking into bigger picture will help me.



Pavol
_______________________________________________
zeromq-dev mailing list
[email protected]
https://lists.zeromq.org/mailman/listinfo/zeromq-dev

Reply via email to