Rupert, first of all thank you for talking the time to go through and comment. Let me try answering the first 4 questions.
On 8/16/07, Rupert Smith <[EMAIL PROTECTED]> wrote: > > Hi, I have tried putting a case forward for three things. > > 1. Methods as classes, rather than exposed arguments. [RA] On a general note, as an API user I like to use arguments rather than classes. I think that's what a majority of users would prefer as it looks more natural. YMMV Reason: Methods created by factories, allowing multi-version support > (although Raphael points out that if the args change significantly then > the > protocol is changing too much between versions, so has gone for a > different > solution to the multi-version issue). [RA] I agree with Rafi here. The point is any significant change will need more than multi version support. So a client or broker may need to rework stuff anyways - changing method arguments is the least of concerns at that time. So we can keep the multi version support simple and nice. Allows one implementation of methods > as byte buffers, another as java fields, for in-vm transport. Keeps open > possibility of native implementation. Allows pass-through processing, > where > method is never decoded or only partially decoded. Also, it might be > possible to do faster serialization/deserialization, using a JVM tweaked > at > the byte code level. I believe that Terracotta (http://terracottatech.com/ > ) > gets up to such tricks. There is also an out-of-date project, > http://www.eecs.harvard.edu/~mdw/proj/old/jaguar/, that does this sort of > thing too, no idea but maybe the Terracotta folks got some ideas from > there. [RA] Sounds interesting. However my experience is that fancy solutions often result in complex code hard to comprehend and difficult to maintain. You heard about YAGNI? "suggests to programmers that they should not add functionality until it is necessary" We can adopt a strategy to keep the door open for all these customizations, but my experience most projects don't even end up doing these things. 2. Full mapping of the protocol 1:1 onto the API. > > I agree that onMessage is the most frequently handled incoming method on > the > client side, but there is the rest of the protocol to consider too. The > API > just isn't low-level if it does not expose everything. [RA] This question tells me that u haven't gone through the doc fully :) MessageListener interface is not even the primary means of exposing message receiving. Did u see the MessagePartListener which is very natural to the way AMQP works ?? It directly exposes (1:1 mapping) the way the protocol works when receiving messages. MassageListener is supported as an Adapter on top of this for users who needs a convenient way of handling small messages. Just to be clear, The API exposes the entire protocol (or the COM layer) except that it provides 3 convenience methods. Connect - which handles connection negotiation Convenient message methods - small messages + streaming support for large messages. Failover. Other than that it exposes everything else 1:1. Can you please point out concrete examples of what is not exposed? Lets start there and work our way through. If for some reason if a user wants to do connection negotiation and failover themselves then they could directly use the com layer. But 99% of the users will prefer the thin API layer outlined in the current code. 3. Use of the inverse symmetry of the API so that the outgoing interface > that the client calls, is identical to the incoming interface that the > broker routing layer implements. [RA] This is actually the case. As Rafi explained before, the Delegate is the inverse of the Invoker. Comm layer can be completely bypassed, and a client can be directly welded > onto the broker. [RA] This can be easily done. Rafi will work on the transport layer to abstract the underlying transport (TCP,SCTP..etc) when he comes back. He just wanted the common use case working before anything else. I think I should add a fourth to this list: > > 4. Be language neutral, that is a suitable API for implementing in any of > our target languages. [RA] This is a question for the AMQP group. From the discussions so far, I gather that the AMQP goups is not ready for providing an AMQP API even if it wants, as the protocol is not stable yet. CORBA made that mistake and eventually suffered the consequences of it. I don't think there is a need for a separate language neutral API from AMQP. IMO the semantics defined by way of classes in the sepc already provides this language neutral API. Implementations in multiple languages (in OO, Functional and procedural - if a pure c client exists) proves that this suffices. Can assume target language is OO? Not sure I'd like to invent an API that > equally well maps onto an OO as well as a functional language ;). [RA] There u go. Defining a language neutral API is not a value bearing exercise. An AMQP implementation in Erlang from Rabbit has already proved that. What if somebody wants to write a pure C client ? To these ends, I have been playing around with the Stub that Raphael > originally posted to this list. I am slowly getting an API into shape, on > my > laptop on the way to and from work on the train, but haven't really the > time > to dedicate to completing it yet. > > Here is a rough outline: > > Everything in the API is an interface first, the comm layer implements it. > I > like interfaces, because you can have multiple implementations. There is > also a toy broker that implements some of the interfaces too, allowing > direct connection of the client onto an in-vm broker. > > Every 'class' in the protocol has two interfaces in the API. One for the > outgoing calls that the client may make to the broker, one for the calls > the > broker may make to the client. > > Every 'method' in the protocol has an interface. > > All the outgoing 'classes' are pulled together into a single interface, > and > all the incoming 'classes' are pulled together into a single interface > that > extends them all. The reason for splitting down on per-'class' basis, is > in > case someone wants to implement a delegate for just one 'class', rather > than > having to implement all methods. The were probably also be no-op abstract > implementations, that can be extended to write delegates that handle just > one 'method' event out of a 'class'. > > Methods are created by a method factory. > > Methods can be called in the context of a connection, or a session. The > initial connection creation and session creation are performed by calling > their 'open' methods. > > The comm layer implements both the incoming and outgoing 'classes', you > have > to ask the factory for the flavour you want depending on the context. For > example the interface for the client to call the broker is called > 'ProtocolBroker' (extends ClassSessionBroker, ClassMessageBroker, etc), > and > the one for the broker to call the client is 'ProtocolClient'.(extends > ClassSessionClient, ClassMessageClient, etc). > > The factory allows you to register delegates, with the comm layer. When > the > comm layer receives incoming frames, it delegates the decoded method calls > onto the delegate (I think just one delegate for the moment, rather than > an > interceptor pattern style chain, not sure, will probably have to do some > kind of chain eventually, xwork/webwork may provide some inspiration for > this). > > The 'toy' broker I have sketched out, implements ProtocolBroker. It also > provides a protocol factory, this factory will throw an exception if you > ask > it to create a ProtocolClient, but it will give you a ProtocolBroker. > > So to write a client against the comm layer, ask its ProtocoFactory > implementation for a ProtocolBroker. To write a client directly against > the > broker routing engine, ask its ProtocolFactory implementation for a > ProtocolBroker. This is point 3 above, about the inverse symmetry of the > interfaces. > > Some methods in the protocol require a response, but all are asynchronous. > For this I am providing a pair of conversation interfaces, with wait for > methods. So for example to open and attach a session, I do: > > ProtocolFactory factory = ... > ProtocolBroker invoker = ... > ConnectionContext connection = ... > ProtoclClient delegate = factory.defaultClientDelegate(); > > MethodOpenSession = factory.getMethodFactory().createOpenSession(...); > > Conversation conversation = factory.createConversation(invoker, delegate); > SessionContext session = conversation.openSession(connection, > openSession); > conversation.waitForSessionAttached(); > > Sorry, for being a bit light on the details. I don't have it in a state I > am > ready to release yet, also it is stuck on my laptop at the moment, as I > can't connect my personal lap-top to the net at work, and my home server > is > down at the moment due to moving house. I will post it to the list, once > it > feels right to me. I have very successfully retro-fitted Raphael's stub > onto > my API, shifting things around a bit, but keeping essentially the same > code. > I just wanted to post to try and keep my ideas alive, as I think they are > worthwhile, and I don't feel that the API at, > http://cwiki.apache.org/confluence/display/qpid/Message+API+Design, > satisfies any of my three criteria. > > The generated API for the comm layer does look to me like a good low-level > API. One thing I would prefer to see though, is it implementing a set of > interfaces. Also, for that set of interfaces not to use generics, > primarily > for backward support for java 1.4, or for non-parametric-polymorphic > language implementation. > > I do agree with the comment that Raphael made on the meeting last week, > that > the push API for large messages, is better than a pull one. Simply because > it will be more natural to write a pull utility on top of a push API, and > a > push API makes less assumptions about a threading model. However, the API > at: http://cwiki.apache.org/confluence/display/qpid/Message+API+Design, > looks very similar to me, to what is already available in JMS as > javax.jms.StreamMessage? > > > On 15/08/07, Rajith Attapattu <[EMAIL PROTECTED]> wrote: > > > > folks, > > > > I have captured the design notes for the new client API at > > http://cwiki.apache.org/confluence/display/qpid/Message+API+Design > > > > This is to give a heads up on the direction we are talking. > > I believe this is extremely close to the ideas we agreed on the dev > list. > > > > Regards, > > > > Rajith > > >
