[zeromq-dev] External Event Loop

Praveen Baratam praveen.baratam+zmq at gmail.com
Sun Jan 2 21:04:40 CET 2011


Hello Jonathan,

I read your code.

The IO and PROBE calls from ZeroMQ.pm are fine. I have writted similar
bindings in C++ using libev and also libevent.

When it comes to handle.pm and in the *read* subroutine - please follow the
inline comments(purple) in read call as below:

sub read {
    my $self = shift;

//////////////////////////////
// this appears redundant
//////////////////////////////
    while($self->readable && $self->has_read_todo){
        $self->_read_once(shift @{$self->read_buffer});
    }

//////////////////////////////
// this too appears redundant
//////////////////////////////
    while($self->readable && $self->has_on_read){
        $self->_read_once($self->on_read);
    }

//////////////////////////////
// why not create a watcher directly
// skipping the above code and
// in the callback from the watcher
// probe the socket and do _read_once
//////////////////////////////

    if($self->has_read_todo || $self->has_on_read){
        # ensure we have a watcher
        $self->read_watcher;
    }
    else {
        $self->clear_read_watcher;
    }
}


You can easily recreate the bug if you do so and also reduce redundancy in
your code.

If fd is already ready for read, your approach saves a system call but most
of the times you will be waiting for data on a socket i.e. waiting for event
on the fd in which case you are probing unnecessarily before actually
creating the watcher.

Its my preliminary opinion.

As far my TestCase is concerned, its just written to recreate the bug and
nothing else.

What I do in my project is that I create a watcher on each socket FD and
then in the callback i probe the socket with ZMQ_EVENTS and if there are
events I will read from the socket or else wait for the next event.

Regards,

Praveen


On Sun, Jan 2, 2011 at 7:27 AM, Jonathan Rockway <jon at jrock.us> wrote:

>
> Apologies if this is a dupe; the zmq-dev mail server did not like my
> mail server's HELO command and rejected my previous post :)
>
> * On Sat, Jan 01 2011, Praveen Baratam wrote:
> > Is there anything wrong with the TestCase I have submitted in my
> > previous mail?
> >
> > Me and my team are eagerly waiting for a reply from ZeroMQ team.
>
> I took a look at your test case, and am confused as to what you are
> trying to achieve.  So I am going to describe how I implemented the
> non-blocking Perl binding for ZMQ, which I am using with libev without
> problems.  It the new ZMQ_EVENTS socktopt in the development version.
>
> I'm going to cover reads, but writes work the same way.  When something
> wants to read a message, it supplies a callback.  The idea is to call
> the callback with the message when it's ready.
>
> When we get a request to read, we start by checking readability of the
> socket via ZMQ_EVENTS.  If the ZMQ_POLLIN is set we do a read (with
> ZMQ_NONBLOCK), and call the callback with the message.  (If a message is
> not read, perhaps due to non-readability of the socket, an exception is
> thrown.  But this has never happened with any socket type, so I'm
> guessing that ZMQ_EVENTS is accurate.)
>
> If ZMQ_POLLIN is not set, then we can't read immediately. In that case,
> we get the ZMQ_FD, and create an IO watcher (ev_io, specifically) on
> that fd.  When the fd becomes readable, we check ZMQ_EVENTS again, and
> do the read if possible.  We then remove the read watcher when we don't
> care about reading anymore.
>
> For reading multiple messages, we just do this in a loop -- check
> readability; if readable: read the message, else: create IO watcher;
> repeat.
>
> This makes sense to me and has worked in all my testing, but I've seen
> various people on the Internet discussing how they do this differently,
> so I'm interested in any feedback as to how this approach is wrong.
>
> Here is my code; a small library providing a function to probe for
> readability ("probe"), and a function to actually create the IO watcher
> and call a callback when the fd is ready ("io").
>
>
> https://github.com/jrockway/anyevent-zeromq/blob/master/lib/AnyEvent/ZeroMQ.pm
>
> I use that at a higher level to write AnyEvent::ZeroMQ::Handle, which is
> how I tie together ZMQ_EVENTS and an IO watcher.
>
>
> https://github.com/jrockway/anyevent-zeromq/blob/master/lib/AnyEvent/ZeroMQ/Handle.pm
>
> The relevant algorithm is in "read":
>
>
> https://github.com/jrockway/anyevent-zeromq/blob/master/lib/AnyEvent/ZeroMQ/Handle.pm#L134
>
> The support function "_read_once" actually does the read,
> "_has_read_todo" returns true if the user of AnyEvent::Handle wants to
> read something (i.e., there are pending callbacks that need messages),
> and "readable", which returns true if ZMQ_EVENTS says the socket is
> readable.
>
> Hope this helps, or that someone can tell me how I've botched this
> terribly :)
>
> Regards,
> Jonathan Rockway
> _______________________________________________
> zeromq-dev mailing list
> zeromq-dev at lists.zeromq.org
> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20110103/1c1687d3/attachment.htm>


More information about the zeromq-dev mailing list