Re: codec changes

2015-03-31 Thread Božo Dragojevič
Given the memory overhead of a pn_data_t before encoding, why not have it
own an encode buffer? it could get by with exactly that grow_buffer()
callback if ownership is the issue .

Bozzo
On Mar 31, 2015 6:10 PM, Rafael Schloming r...@alum.mit.edu wrote:

 Hi Alan,

 Sorry I didn't comment on this sooner, I didn't have time to comment on
 your original review request during my travels, however I do have some
 thoughts on the changes you made to the codec interface. I noticed you
 added a separate accessor for the size:

 ssize_t pn_data_encoded_size(pn_data_t *data);

 This is alongside the original encode method:

 ssize_t pn_data_encode(pn_data_t *data, char *bytes, size_t size);

 I think this API choice while nice in that it is backwards compatible is
 also going to result in code that is roughly twice as slow as it needs to
 be in the most common case. Based on my experience implementing and
 profiling codec in C, Python, and Java, computing the size of the encoded
 data seems to usually be roughly the same amount of work as actually
 encoding it regardless of the implementation language. Therefore code like
 this:

 if (buffer_size()  pn_data_encoded_size(data)) grow_buffer();
 pn_data_encode(data, buffer, buffer_size());

 Can end up being roughly twice as slow as code like this:

 ssize_t err;
 while ((err = pn_data_encode(data, buffer, buffer_size())) ==
 PN_OVERFLOW) {
 grow_buffer();
 }

 Admittedly the latter form is much more awkward in those cases where you
 don't care about performance, so I'm all for providing something nicer, but
 I think a better API change would be to steal a page from the C stdio.h
 APIs and have pn_data_encode always return the number of bytes that would
 have been written had there been enough space. This allows you to write the
 simplified encode as above:

 if (buffer_size()  pn_data_encode(data, NULL, 0)) grow_buffer();
 pn_data_encode(data, buffer, buffer_size());

 Or use a more optimal form:

ssize_t n = pn_data_encode(data, buffer, buffer_size());
if (n  buffer_size()) {
grow_buffer();
pn_data_encode(data, buffer, buffer_size());
}

 This makes the slow/convenient form possible, and provides some options
 that are a bit less awkward than the loop, but it also makes it very clear
 that when you use the slow/convenient form you are incurring roughly twice
 the cost of the alternative.

 Normally I wouldn't be overly fussed by something like this, and I realize
 what I'm suggesting is a breaking change relative to what you provided, but
 based on what profiling we've done in the past, codec is probably the most
 significant source of overhead that we add to an application, and exactly
 this sort of double encode effect is almost always one of the first things
 you hit when you try to optimize. Given this, I think it would be a good
 thing if the API accurately reflects the relative cost of the different
 styles of use.

 Thoughts?

 --Rafael



Re: Thread-safety rules of proton

2015-03-19 Thread Božo Dragojevič
I understand it this way, too

Bozzo
On Mar 19, 2015 8:35 PM, Alan Conway acon...@redhat.com wrote:

 I don't think I'm saying anything new here, just want to confirm my
 understanding of the thread-safety rules of the proton library.

 Separate pn_connections can be processed concurrently in separate
 threads. A given pn_connection_t must NOT be used concurrently.

 All objects associated with a connection must be handled in the same
 thread context that handles that connection. This is because calls on
 all objects can potentially find their way back to the shared connection
 object. For example you can get all the way from a delivery to the
 containing connection:

 pn_delivery_t *pn_work_next(pn_delivery_t *delivery)
 {
   assert(delivery);

   if (delivery-work)
 return delivery-work_next;
   else
 return pn_work_head(delivery-link-session-connection);
 }

 The exception (I think/hope) is pn_message_t. pn_message_t does not (I
 think) have any pointers to shared objects. So once a pn_message_t has
 been decoded it IS ok to handle separate pn_message_t objects in
 separate threads (provided any individual pn_message_t instance is never
 used concurrently of course)

 Is that about correct?

 Cheers,
 Alan.




Re: [VOTE]: migrate the proton repo to use git

2014-10-30 Thread Božo Dragojevič
[ X] Yes, migrate the proton repo over to git.


Re: landing events branch

2014-07-10 Thread Božo Dragojevič
On Jul 10, 2014 6:41 PM, Rafael Schloming r...@alum.mit.edu wrote:

 Hi Everyone,

 I wanted to give people a quick heads up. I would like to land the events
 branch soon. If you don't use the events API then this probably won't
 impact you, however if you do then you may experience some compilation
 failures. This is because of the following changes:

 The PN_{CONNECTION,SESSION,LINK}_LOCAL_STATE events have been decomposed
 into two distinct events:

   PN_{CONNECTION,SESSION,LINK}_OPEN and PN_{CONNECTION,SESSION,LINK}_CLOSE

 Similarly, PN_{CONNECTION,SESSION,LINK}_REMOTE_STATE has been decomposed
 into:

   PN_{CONNECTION,SESSION,LINK}_REMOTE_OPEN and
 PN_{CONNECTION,SESSION,LINK}_REMOTE_CLOSE

 To fix your code all you need to do is adjust your switch statements to
 match on the new names, e.g. something like this:

 ...
 case PN_CONNECTION_REMOTE_STATE:
 ...

 Would become something like this:

 ...
 case PN_CONNECTION_REMOTE_OPEN: // fall through
 case PN_CONNECTION_REMOTE_CLOSE:
 ...

 Please give me a shout if this will cause a problem for you, otherwise I
 will land the branch in a day or two.


When speed reading the new event api the other day,  the change seemed
quite large, but such a mechanic change seems easy to adapt.

Bozzo