Let's start Scheme

2022-06-20

AMQP

Sagittarius supports AMQP, Advanced Message Queue Protocol, since probably 0.6.x, I don't recall which version, to be honest. The reason I wanted to support this was because I was using QM, I think IBM MQ, at that moment at my work and wanted to send a message from a command-line, instead of using a Web browser. Unfortunately, the version of MQ was too old and didn't support AMQP yet. So, I couldn't use it for the purpose that I wanted. Nevertheless, it's there and it's supported.

Now, I want to write a demo application to show what Sagittarius can do out of the box. One of the main reasons I've made Sagittarius is that I can use it for daily commercial work. So, I thought it's nice to have a demo of integration with external systems, not only for HTTP but also some other protocols which Sagittarius supports out of the box. Then, I realised that the current implementation of AMQP client is not really efficient nor doesn't work as I expected.

To explain what doesn't work, I first need to explain how the AMQP connection and session work. An AMCP connection is a physical connection, which holds an actual socket. Now, under a connection, there are sessions. A session is a virtual separation of input and output channels. This means if a connection has multiple sessions, input or output messages need to be dispatched properly to the associated session. It's easier to see it in a diagram:

Session under connection

  Client App                                        Broker
+-------------+                                +-------------+
|             |################################|             |
|   +---+     |--------------------------------|    +---+    |
|   | C |     |            Session             |    | Q |    |
|   +---+     |--------------------------------|    +---+    |
|             |################################|             |
+-------------+                                +-------------+

Multiple sessions

    Session<------+                           +------>Session
(ICH=1, OCH=1)    |                           |    (ICH=1, OCH=1)
                 \|/                         \|/
    Session<--> Connection <---------> Connection <-->Session
(ICH=2, OCH=3)   /|\                         /|\   (ICH=3, OCH=2)
                  |                           |
    Session<------+                           +------>Session
(ICH=3, OCH=2)                                     (ICH=2, OCH=3)

        Key: ICH -> Input Channel, OCH -> Output Channel 
      

For the original diagram and the specification, you can refer 2.1.2 Communication Endpoints

The point is that the physical connection is only one, however virtual connection/session can be multiple simultaneously. However, the current implementation of AMQP on Sagittarius can't handle this due to the fact that the socket is shared by the sessions (or underlying receivers).

So, if I want to do it properly, the design must be changed sort of like this:

      +------------------+
      |    Connection    |  +--> Session1
<IN>  |  +------------+  |  |
======+==+=> socket  -+--+--+--> Session2
      |  +------------+  |  |
      |     |     /|\    |  +--> Session3
      +-----+------+-----+
            |      |
           \|/     |
       +---------------+
       |  Frame reader |
       +---------------+

And possibly, the reading frame process is running on a background thread, once the connection is established.

Let's see what I can do...