Hit "send" a bit too quickly:

The "official" proton docs are linked from the proton release web page:

http://qpid.apache.org/releases/qpid-proton-0.5/index.html


These are generated from the header file - we're missing an overview page 
though (https://issues.apache.org/jira/browse/PROTON-462)

Justin - can you remove those old proton api docs Fraser hit from our web site?

> > http://qpid.apache.org/components/messenger/book/sending-and-receiving.html

thanks,

-K


----- Original Message -----
> From: "Ken Giusti" <kgiu...@redhat.com>
> To: users@qpid.apache.org
> Sent: Tuesday, November 19, 2013 3:17:37 PM
> Subject: Re: using proton messenger *asynchronously*
> 
> Hi Fraser,
> 
> ----- Original Message -----
> > From: "Fraser Adams" <fraser.ad...@blueyonder.co.uk>
> > To: users@qpid.apache.org
> > Sent: Sunday, November 17, 2013 7:04:53 AM
> > Subject: using proton messenger *asynchronously*
> > 
> > Hey all,
> > I've been messing around trying to get messenger to do something in
> > asynchronous mode. The comments here:
> > http://qpid.apache.org/components/messenger/book/sending-and-receiving.html
> > 
> > Suggest that it's possible - though the doc there probably needs an edit
> > because |pn_messenger_send(messenger) |isn't legal - it needs a second
> > parameter, the actual prototype is:
> > /*
> >   * @param[in] messenger the messager
> >   * @param[in] n the number of messages to send
> >   *
> >   * @return an error code or zero on success
> >   * @see error.h
> >   */
> > PN_EXTERN int pn_messenger_send(pn_messenger_t *messenger, int n);
> > 
> > But that's by the by:
> > 
> > 
> > When I started playing with this I eventually figured out that I needed
> > to have:
> > pn_messenger_set_blocking(messenger, false);
> > 
> > After I've created a messenger, as well as doing:
> > pn_messenger_send(messenger, 0);
> > 
> > 
> > But it all seems a lot more cryptic than that. Under the hood there's a
> > call to pn_messenger_tsync, which in blocking mode eventually ends up
> > blocking on a poll and has a while loop internally. Now that tsync call
> > seems to do a whole bunch of things actually leading to sends and
> > receives of the sockets, so it seems just calling pn_messenger_send in
> > non-blocking mode isn't enough and I need to call
> > pn_messenger_work(messenger, 0); too.
> > 
> 
> You're correct here - it appears that the web page you reference hasn't been
> updated since Rafi added the non-blocking stuff.  You definitely need to
> call pn_messenger_work() in order to have data hit the wire.
> 
> > I've attached some *really hacky* code. The code is pretty rubbishy, in
> > the case of send it's calling pn_messenger_send then calling a main loop
> > that does pn_messenger_work(messenger, 0); periodically. The select to
> > sleep every second is a massive hack, and I've tried different values of
> > sleep - ultimately I'd want it to be a proper asynchronous application.
> > 
> > 
> > As far as I can see using the send and recv I've attached things get as
> > far as completing the AMQP negotiation, but the actual message isn't
> > being sent and it *looks like* something to do with credit.
> > 
> > I've hacked around in proton "instrumenting" it - OK I've added a bunch
> > of printfs :-)
> > 
> > Hands up who knows that code best? fancy volunteering to document the
> > call graph, trying to work my way around that made my *head explode* ;-D
> > I'm sure it's easy when you know, but trying to figure the path of the
> > actual message.........
> > 
> > 
> > I *think* that there's some sort of "store" where pn_messenger_put
> > actually puts the message and at some point the message should be
> > retrieved from there by the transport.
> > 
> > Looking through transport.c I've added printfs to
> > "pn_output_write_amqp_header" and "pn_output_write_amqp" and can see
> > those getting called and pn_process(transport) seems to be getting
> > called too.
> > 
> > Looking at where I'm at; the message is being put into the store
> > 
> > pn_messenger_put
> > calling pn_buffer_append 93
> > 0 83 112 -48 0 0 0 11 0 0 0 5 66 80 4 64 66 82 0 0 83 115 -48 0 0 0 49 0
> > 0 0 13 64 64 -95 14 97 109 113 112 58 47 47 48 46 48 46 48 46 48 64 64
> > 64 64 64 -125 0 0 0 0 0 0 0 0 -125 0 0 0 0 0 0 0 0 64 82 0 64 0 83 119
> > -95 12 72 101 108 108 111 32 87 111 114 108 100 33
> > 
> > So that's the "Hello World!" at the end of the buffer :-) but when I
> > print out the values needed for the test in pn_process_tpwork_sender I
> > keep getting:
> > 
> > pn_process_tpwork_sender state->sent = 0 delivery->done = 1 93
> > ssn_state->remote_incoming_window = 0
> > link_state->link_credit = 0
> > 
> > 
> > This *seems* to be saying that the message is still in the store but
> > remote_incoming_window and link_credit are zero. That basically prints
> > out every time I call pn_messenger_work(messenger, 0);
> > 
> > 
> > There's clearly something I'm missing? There wasn't anything in the
> > synchronous send/recv that explicitly set credits though? I've spent
> > most of the weekend tearing my hair out on this, so I'd be grateful for
> > any ideas.
> > 
> 
> You're correct - it does come down to credit.  In your recv.c code, the
> main_loop needs to supply a credit count to the pn_messenger_recv() call:
> 
>     // XXX pn_messenger_recv(messenger, 0);
>     pn_messenger_recv(messenger, 1);
> 
> This will cause the receiver to send a "flow" frame.
> 
> All in all, your code is pretty close - I've made a few tweaks (attached).  I
> think the big difference is the call to pn_messenger_work() on the sender -
> you need to call that until the outgoing message has been sent
> (pn_messenger_outgoing() == 0).
> 
> And from what I can tell - again, not documented - you need to keep calling
> pn_messenger_work() until it returns a non-zero value.  This is inconsistent
> with the Java variant (which returns 0 when there's no more work to do) -
> I've got a proposed fix pending (https://reviews.apache.org/r/15458/diff/#5)
> for 0.6.
> 
> As you've noticed the docs tend to not keep up with the code changes, and
> that makes things difficult to understand.  Usually the header files are
> more up to date.  Personally, I've learned most from reading the python unit
> tests (tests/python/proton_tests/*).
> 
> > 
> > I was serious about the call graph documentation BTW, being pretty new
> > to the code base it was pretty daunting following the various levels of
> > indirection and I'm still nowhere near actually understanding how it
> > works, how do you guys find your way around when it comes to debugging -
> > is it just experience or are you using other debug tools?
> > 
> > Cheers,
> > Frase
> > 
> 
> 
> BTW, if you set an environment variable called "PN_TRACE_FRM" to one:
> 
> $ export PN_TRACE_FRM=1
> 
> proton will dump a trace of the traffic "on the wire" when you run your
> programs.  Doing that, I could see that the code was getting "stuck" at the
> point where I would think recv should issue a flow frame.
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscr...@qpid.apache.org
> > For additional commands, e-mail: users-h...@qpid.apache.org
> 
> --
> -K
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@qpid.apache.org
> For additional commands, e-mail: users-h...@qpid.apache.org

-- 
-K

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@qpid.apache.org
For additional commands, e-mail: users-h...@qpid.apache.org

Reply via email to