----- Original Message ----- > Hi Everyone, > > In a recent thread I alluded to some improvements I have in mind for the > engine API and promised a separate post on the topic, so here it is. > > There are two areas where I'm interested in extending the API. These > extensions are strictly speaking independent of each other, but at the same > time somewhat complimentary in their utility. > > The first area would be adding a formal Container class to the engine API. > If you are familiar with the AMQP specification then you might have noticed > that while the engine API models connections, sessions, and links pretty > faithfully to how they are defined in the specification, one notable > difference is that the engine API doesn't explicitly model the concept of > an AMQP Container. I believe adding such a class to the engine API would > allow us to refactor some of the more generally useful stuff that Messenger > does into the engine proper, while leaving the less desirable stuff (such > as blocking behaviour and hard coded driver) in messenger proper. > > The second area is providing an event oriented interface into the engine. > One of the original ideas behind the engine design is that you don't need > event callbacks because the engine itself is simply a state machine, and > changes in its state are only ever triggered by calling into the engine > API. This means that whenever you make such a call you can simply query to > see if anything relevant has changed. While this is strictly speaking true, > the whole "query to see what has changed part" is responsible for a fair > amount of biolerplate code in using the engine and makes for a steeper > learning curve than is desirable. So the idea behind an event oriented > interface is to provide a uniform way of discovering what has changed that > has a strong analog to the event callback systems most people are used to, > but at the same time doesn't go quite so far as to use callbacks. > > The details of this event oriented interface are somewhat TBD, but my > thinking right now on this is to introduce a Collector object that can be > registered with an arbitrary number of Containers and/or Connections. The > Collector will work in concert with an Event class. > > The Event class will contain optional references to at most one of each of > the following: Container, Connection, Session, Link, Delivery. The event > class will also have type, i.e. an enum field indicating what of interest > may have occurred. > > When something of interest happens to a Container, Connection, Session, > Link, or Delivery, the library will check to see if there is a Collector > registered, and if so create/initialize an Event that points to the > relevant engine objects and indicates the appropriate type. Note that no > callback occurs here, the Collector just holds the event until the > application comes looking for it. > > The Collector of course has an API for accessing and consuming any events. > > There are a couple of important principles to note. As stated above there > are no callbacks in this interface, this makes it easy to swig into other > languages, however it should be only a few lines of code to write a > dispatch loop on top of the swigged version of this API, i.e.: > > for event in collector: > dispatch(event) > > Another important point is that Events are simple transient value objects. > They don't carry any significant state in and of themselves, rather they > are simply pointers to part of the existing engine state machine that may > be of interest. The protocol state is still entirely encapsulated in the > engine objects proper, not in the Events.
Is there a potential problem here if state pointed at by event A is changed by event B in the same block of input data (i.e. without the user being able to see event A until after B has been put in the queue)? That would make A's pointer misleading at best since it doesn't point at the data resulting from event A, and makes processing B a challenge if the data has already been processed while looking at it via A.
