On Tue, Mar 5, 2013 at 2:01 PM, Rafael Schloming <r...@alum.mit.edu> wrote: > On Tue, Mar 5, 2013 at 10:42 AM, Michael Goulish <mgoul...@redhat.com>wrote: > >> >> quoth Rafi: >> >> > The semantics of pn_messenger_put allow it to send if it can do so >> without >> > blocking. >> >> >> So, am I understanding correctly? -- I should be able to get messages >> from my sender to my receiver just by calling put() -- if the receiver >> is ready to receive? >> > > Not necessarily, the receiver being ready just means you are unblocked on > AMQP level flow control. You could also potentially block on the socket > write (i.e. TCP level flow control). You need to be unblocked on both for > put to succeed. > > >> >> The only transmission difference between put() and send() is that send() >> will actually block until they're all sent (or timeout hits). put() should >> get rid of all the messages that aren't blocked, and leave all that are. >> >> . . . >> >> Because what I'm seeing is -- with my receiver hanging in recv(), >> I put 5 messages. Sender sits there for a while. No messages arrive at >> receiver. Then sender calls send() -- and all 5 messages arrive at >> the receiver. >> >> This is true whether on the receiver side, I use >> >> pn_messenger_recv ( messenger, 100 ); >> pn_messenger_recv ( messenger, 5 ); >> pn_messenger_recv ( messenger, 1 ); >> or >> pn_messenger_recv ( messenger, -1 ); >> >> >> That's why it seemed two-stage to me. put() seems to gets them staged, >> send() seems to shove them out the door. >> >> No? >> Or is this a bug? >> > > What I said was put is *allowed* to send optimistically, not that it is > required to. It actually did send optimistically in a previous version of > the code, however I commented that line out. > > I would say the documented semantics of put and send should allow the > implementation the flexibility to do any of the following: > > 1) optimistically transmit whatever it can everytime so long as it > doesn't block > 2) never bother transmitting anything until you force it to by calling > send > 3) anything in between the first two, e.g. magically transmit once you've > put enough messages to reach the optimal batch size > > The reason for the behaviour you are observing is that we currently do > option 2 in the C impl, however we've done option 1 in the past (and I > think we do option 1 still in the Java impl), and we will probably do > option 3 in the future.
This is a good explanation that we need to put in the docs, as Application developers certainly need to know how it behaves. If one were to use the current C impl, it certainly gives the impression that put() is meant to write messages into your internal buffer and send() will actually write it to the wire. Unfortunately some applications will depend on this behaviour, even though it's not advisable If we are to change from say #2 to #1 or even #3 we need to release note it prominently. I think the best solution is to make this behaviour configurable, and advertise the default very prominently. This way application developers will know exactly what they are getting instead of us making changes underneath. Rajith > --Rafael