Some suggestions about how to handle the 0-10 update, debate is
encouraged. I believe this is close enought to current architecture
to be implemented without major trauma but more aligned with spec and
more flexibile.
* 1. All (and only) generated code goes in namespace amqp_0_10
Basis for future multi-version support.
* 2. Frame/segment data types
framing::Frame // command, control, header or body frame (current AMQFrame)
framing::Segment // aggregation of frames, handle segment start/end flags.
framing::MethodSegment: public Segment // complete method segment
framing::HeaderSegment: pubolic Segment // header segment (cf AMQHeaderBody)
framing::BodySegment: public Segment // body segment
framing::Assembly: { // base class for generated decoded methods cf
AMQMethodBody
optional HeaderSegment, BodySegment
// A method always has a complete decoded method segment but
// initially does not have header/body segments, they can be
// added in at various points in the handler chain.
}
Rationale:
- separate aggregate segments from atomic frames.
- represent a Assembly (command or control)
- allow _optional_ attachment of header/body segments to method.
Alternative is to leave them as un-aggregated frames.
* 3. Handler types
FrameHandler { handle(Frame&)=0; } // as now.
// Handle aggregated commands/controls and un-aggregated header/body frames.
AssemblyHandler: public FrameHandler { handle(Assembly&)=0; }
// Invokation interface for commands and un-aggregated header/body frames
// cf. SemanticHandler
CommandHandler : public FrameHandler, public BrokerAdapter
Rationale:
Assembly segments are always aggregated and parsed early.
Header/body may be aggregated at different points e.g. cluster handler
may or may make header-based descisions.
A handler that does aggreagate a header/body segment attaches it to
the Assembly so later handers can use it. A handler that does not
aggregeate simply forwards individual header/body frames.
* 4. Handler insertion points
There are several points where add-on components can insert their own
handlers into the logic:
connection incoming FrameHandler:
- aggregates all controls & commands segments.
- invokes connection controls on ConnectionHandler
- forwards session controls, commands as methods to session
AssemblyHandler.
- forwards un-aggregated header/body frames as frames to session
AssemblyHandler
session incoming AssemblyHandler:
- invokes session controls on SessionHandler.
- forwards command Assemblys to CommandHandler (cf SemanticHandler)
- forwards un-aggregated header/body frames to CommandHandler
session outgoing AssemblyHandler: all outgoing Assemblys & frames.
Additional handlers can be inserted before the standard handlers
at each point above.
* Relationship to existing code:
FrameHandler: remains at the connection level, but no longer contains a
decoded AMQBody, just a frame type, size and bytes.
*Segment classes: Replace AMQ*Body subclasses.
Aggregate frames and decode segments.
AssemblyHandler: replaces most FrameHandlers. Where currently we do
frame.getMethod(), AssemblyHandlers will do
assembly.getMethod(). Handlers that aggregate or use header/body
segments will need to look first at the Assembly to see if they are
already aggregated. If not they will aggregate them frame by frame and
attach to the assembly.
CommandHandler: new name for SemanticHandler.