Oh, and +1 to the patch.  The names are much better, and the descriptions make 
the use model much clearer.

-K

----- Original Message -----
> "What we've got here is failure to communicate."
> 
> 
> > There aren't necessarily distinct
> > input/output
> > buffer objects, rather the whole transport interface itself is
> > really
> > just
> > single structure (a [transforming] byte queue) with push/peek/pop
> > corresponding exactly to any standard queue interface.
> 
> Aha!  Well, that explains it - I've always though that the transport
> was composed of two separate buffers - one for input, the other for
> output.  At least, that's my interpretation of the existing API.
> 
> A "transforming byte queue" didn't immediately pop into my mind when
> reading these new APIs.  You may want to add a bit of documentation
> to that patch explaining this meme before the APIs are described.
>  Would be quite useful to anyone attempting to implement a driver.
> 
> 
> -K
> 
> ----- Original Message -----
> > Looks like the attachement didn't make it. Here's the link to the
> > patch on
> > JIRA:
> > https://issues.apache.org/jira/secure/attachment/12568408/transport.patch
> > 
> > --Rafael
> > 
> > On Thu, Feb 7, 2013 at 8:10 AM, Rafael Schloming <r...@alum.mit.edu>
> > wrote:
> > 
> > > Here's a patch to engine.h with updated docs/naming. I've
> > > documented what
> > > I believe would be future lifecycle semantics, however as I said
> > > before I
> > > think an initial patch would need to be more conservative. I
> > > think
> > > these
> > > names would also work with input/output prefixes, although as the
> > > interface
> > > now pretty much exactly matches a circular buffer (i.e. a byte
> > > queue), I
> > > find the input/output prefixes a bit jarring.
> > >
> > > --Rafael
> > >
> > >
> > > On Thu, Feb 7, 2013 at 5:53 AM, Rafael Schloming
> > > <r...@alum.mit.edu>
> > > wrote:
> > >
> > >> On Wed, Feb 6, 2013 at 5:12 PM, Rafael Schloming
> > >> <r...@alum.mit.edu>wrote:
> > >>
> > >>> On Wed, Feb 6, 2013 at 2:13 PM, Ken Giusti <kgiu...@redhat.com>
> > >>> wrote:
> > >>>
> > >>>> Rafi, I agree with the rational behind these changes.
> > >>>>
> > >>>> >     /** Return a pointer to a transport's input buffer. This
> > >>>> >     pointer
> > >>>> >     may
> > >>>> >      * change when calls into the engine are made.
> > >>>>
> > >>>> I think we'll need to be a little more liberal with the
> > >>>> lifecycle
> > >>>> guarantee of these buffer pointers.  Drivers based on
> > >>>> "completion" models
> > >>>> (rather than sockets) could be forced to do data copies rather
> > >>>> than
> > >>>> supplying the pointer directly to the completion mechanism.
> > >>>>
> > >>>
> > >>> That sentence was actually supposed to be deleted. The
> > >>> sentences
> > >>> after
> > >>> that describes the intended lifecycle policy for the input
> > >>> buffer:
> > >>>
> > >>>   Calls to ::pn_transport_push may change the value of this
> > >>>   pointer and
> > >>> the amount of free space reported by ::pn_transport_capacity.
> > >>>
> > >>>
> > >>>>
> > >>>> Could we instead guarantee that pointers (and space) returned
> > >>>> from the
> > >>>> transport remain valid until 1) the transport is released or
> > >>>> 2)
> > >>>> the
> > >>>> "push"/"pop" call is made against the transport?
> > >>>>
> > >>>
> > >>> That is in fact what I intended for push. For pop this would
> > >>> place a lot
> > >>> more restrictions on the engine implementation. Say for example
> > >>> peek is
> > >>> called and then the top half is used to write message data.
> > >>> Ideally there
> > >>> should actually be more data to write over the network, which
> > >>> means that
> > >>> the transport may want to grow (realloc) the output buffer, and
> > >>> this of
> > >>> course is more complex if the external pointer needs to stay
> > >>> valid. Given
> > >>> that at worst this will incur an extra copy that is equivalent
> > >>> to
> > >>> what
> > >>> we're currently doing, I figured it would be safer to start out
> > >>> with more
> > >>> conservative semantics. We can always relax them later when we
> > >>> have had
> > >>> more time to consider the implementation.
> > >>>
> > >>>
> > >>>> Or perhaps a reference count-based interface would be safer?
> > >>>>  Once the
> > >>>> driver determines there is capacity/pending, it "reserves" the
> > >>>> buffer and
> > >>>> is required to "push"/"pop" to release it?
> > >>>>
> > >>>> Oh, and those names absolutely stink. ;)  It's unclear from
> > >>>> the
> > >>>> function names what components of the transport they are
> > >>>> affecting.  I'd
> > >>>> rather something more readable:
> > >>>>
> > >>>> pn_transport_capacity() --> pn_transport_input_capacity()
> > >>>> pn_transport_buffer() -> pn_transport_input_buffer()
> > >>>> pn_transport_push() --> pn_transport_input_written()
> > >>>>
> > >>>
> > >>> I think your names (and my documentation) actually suffer from
> > >>> exposing
> > >>> too much of the implementation. There aren't necessarily
> > >>> distinct
> > >>> input/output buffer objects, rather the whole transport
> > >>> interface
> > >>> itself is
> > >>> really just single structure (a [transforming] byte queue) with
> > >>> push/peek/pop corresponding exactly to any standard queue
> > >>> interface.
> > >>>
> > >>> FWIW, I do agree pn_transport_buffer() could be better, however
> > >>> capacity, pending, push, peek, and pop all correspond to pretty
> > >>> much every
> > >>> standard queue/circular buffer/stack interface I've ever seen,
> > >>> and my hasty
> > >>> documentation notwithstanding, I think that is a good meme to
> > >>> take
> > >>> advantage of, particularly since the push/peek/pop semantics
> > >>> and
> > >>> their
> > >>> relationship to each other is actually quite important in
> > >>> guaranteeing that
> > >>> the pitfall occurring in PROTON-222 doesn't come up when people
> > >>> code their
> > >>> own drivers.
> > >>>
> > >>
> > >> To elaborate on this a little, I think the key part of the meme
> > >> that I
> > >> like is how peek strongly signals "non-destructive-read" and pop
> > >> strongly
> > >> signals a destructive operation. I don't get that same
> > >> destructive
> > >> operation sense from output_written, and I think particularly
> > >> when
> > >> considering the lifecycle semantics, the
> > >> non-destructive/destructive nature
> > >> of the operations is kind of key.
> > >>
> > >> FWIW, I can buy the input/output prefix as it's possibly equally
> > >> valid to
> > >> view the interface as a queue head and a queue tail that aren't
> > >> on
> > >> the same
> > >> queue, however I would personally omit them for two reasons (1)
> > >> the notion
> > >> of a transforming queue signals to the user that when you
> > >> provide
> > >> input,
> > >> you should expect there to be output, and (2) I appreciate
> > >> brevity. ;-)
> > >>
> > >> --Rafael
> > >>
> > >>
> > >
> > 
> 

Reply via email to