qpid-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alan Conway <acon...@redhat.com>
Subject Re: 'client' APIs again
Date Mon, 11 Aug 2014 14:01:17 GMT
On Thu, 2014-07-31 at 11:52 +0100, Gordon Sim wrote:
> Following on from the approach taken by Rafi in his demo of the new 
> event support in the proton engine, I've sketched out a few examples for 
> common 'client' scenarios using the proton engine and a 'toolkit' of 
> useful event handlers and utilities.
> The idea behind this is to explore whether this approach is feasible as 
> a general purpose API. It is a reactive style of programming, and is at 
> present fully asynchronous/non-blocking.
> Many more examples are need to ensure all aspects are fully considered, 
> but I think there is enough there to give an idea of the approach that 
> we can then discuss and refine collectively. (Clearly the toolkit could 
> also be expanded to cover higher-level and richer concepts as well).
> The Qpid Messaging API would remain, but Proton would be an alternative, 
> particularly suited for fully asynchronous applications with the full 
> power and flexibility of the engine where needed, but with the common 
> cases made simpler.
> I've focused on python, but I think the approach could be extended to 
> other languages. There is a little bit of 'tutorial' style text to 
> introduce the examples (some reference documentation around the added 
> utilities would also be needed):
>      http://grs.github.io/proton_examples/html/
> and the examples and utility code (some of which are based on Rafi's 
> demo code) needed to run them is here:
>      https://github.com/grs/examples
> I think this looks like a promising approach to make proton more 
> understandable and usable, improve AMQP adoption and get consensus on a 
> clearer roadmap as far as Qpid APIs is concerned. However as always I'm 
> eager to hear your thoughts! Don't hold back on criticism or voicing 
> disagreement, it is better to have a frank conversation.

This is a great start! A few random comments:

Naming: I hate things called *_tools, *_utils etc. We should find a more
descriptive name. Not foo or fred or whatchymacallit or dingdong or
doofer either. Ideally these classes might all just end up in the proton
package, or maybe as a subpackage like proton.events or proton.reactor.

Runtime is a bit vague as a name as well though I haven't got a better

Get rid of Runtime.DEFAULT. Developers who want a global instance should
make their own and be responsible for its scope:

    DEFAULT = Runtime()

We definitely should not provide a global in the library (I have
suffered horribly in the past from this mistake. Seems harmless at first
but creates nightmarish startup & shutdown ordering issues.)

I'd modify the Runtime constructor a little: 

class Runtime:
    def __init__(self, handlers=None):
        if handlers is None: handlers = [FlowController(10)]
        self.handlers = handlers
That make it possible to be clear about whether you want default
handlers Runtime() or no handlers Runtime([])

Example ordering: I would put the direct example first. People want to
see something work right away, it is annoying if the first thing you
have to do is set up some extra software. I think the broker example
second would be fine, even if it is a line shorter.

Waiting for subscriptions with direct connections: one of the things
that bit me hard and often with proton is waiting for things to be
ready. In particular if you create a receiver & sender on separate
connections and send immediately you have a race condition where the
message will sometimes be lost because the sender sent it before the
subscription was actually active. This is quite infuriating to debug.

You dodge the issue by using the same connection for sender & receiver
which is not the case for any but the most trivial example. 
I suggest you face this head on: the direct example should show how to
create a receiver on one connection, wait till it is active, then send
on a different connection.

Reconnect: needs more connection lifecycle events (connected,
heartbeats) but I see you are planning to address this.

Messages and threads: once received an app will want to dispatch
messages based on address and other properties and allocate processing
to threads in various ways. This is (should be) orthogonal to the API
you are designing here but we need to make sure we have adequate thread
safety and don't create limitations in the API that make things
difficult. E.g. the app may want to process messages from a single
proton connection (i.e. a single event stream) in multiple threads and
send reply messages back to the same connection from arbitrary threads.
We should also make it possible for a single thread pool to be used to
handle proton and application events.

MessagingContext: I found this a bit confusing. I got the impression
that its an abstraction over either a session or a connection, but I am
not too clear what purpose it serves.

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

View raw message