...
Gliffy Diagram |
---|
size | L |
---|
name | Echo Engine |
---|
align | center |
---|
version | 2 |
---|
|
Let's start by making our example do something a little more interesting. We can add a query interface to our engine as depicted below. The I/O portion of our application still views the engine as an ordinary circular buffer, however we can now add application logic that uses the query interface to take action. The exact nature of the query interface depends on the protocol and on the engine internals. A simplistic query interface might just provide a byte count of data passing through, whereas a more sophisticated engine could decode and make available semantic content embedded within the byte stream. While a little bit more capable than a simple echo engine, this kind of engine is still just a simple data structure with some added interrogatives, and so retains the desired decoupling and portability.
Gliffy Diagram |
---|
size | L |
---|
name | Echo Engine with Query Interface |
---|
align | center |
---|
version | 2 |
---|
|
Now consider modifying our example to be a simple request/response protocol where every response is a predefined function of each request. We can provide an engine for this kind of protocol by modifying our simple echo engine to detect requests and replace them with responses. With the transformation function entirely encapsulated inside the engine, the interface presented is completely identical to our original echo engine. However, unlike the echo engine, we now have the ability to capture a larger class of protocols.
Gliffy Diagram |
---|
size | L |
---|
name | Simple Request-Response Engine |
---|
align | center |
---|
version | 2 |
---|
|
Now just as we did with the echo server, we can also extend the simple request/response scenario with a query interface as depicted below. And as before, our engine is still just a data structure with well defined interfaces that keep it decoupled and portable.
Gliffy Diagram |
---|
size | L |
---|
name | Simple Request-Response Engine with Query Interfac |
---|
align | center |
---|
version | 2 |
---|
|
Despite being able to capture a large class of protocols, the simple request/response engine still has some significant limitations. For example if the response transformation requires accessing a file, as is the case with a classic HTTP implementation, our engine is no longer decoupled from the OS, and could in fact block on file I/O. Also, if the request is actually invoking application logic such as with an RPC protocol or with most modern usage of HTTP, we simply can't pre-define the result within the confines of our library. To accommodate these scenarios, we need to modify our engine a little further to allow the application to control aspects of the response. To do this we add a control interface that can be used in conjunction with the query interface to inspect a request and modify the response.
...
Gliffy Diagram |
---|
size | L |
---|
name | Request-Response Engine |
---|
align | center |
---|
version | 3 |
|
While the above design nicely captures a very general class of protocol, it is still limited to protocols that use only request/response style interactions. The output bytes are always a function of the input bytes, even though the nature of that function may be influenced by the control interface. The final step to a fully general purpose protocol engine is to define the output bytes as a function of both the input bytes and the control interface as depicted below. This allows for fully general protocols whose interactions are not so regimented as request/response.
...
Gliffy Diagram |
---|
size | L |
---|
name | General Engine |
---|
align | center |
---|
version | 3 |
|
A further refinement of the general purpose engine is to separate the control interface into a distinct entity with its own lifecycle. This entity can be bound to a given transport and then unbound. This separation formalizes the two facets of the engine interface discussed above into a bottom half that can keep a very simple I/O oriented view of the world, and a top half that reflects the high level application interface to the protocol. The distinct lifecycle also permits the control interface to carry state across multiple physical connections, which can allow for a much more sophisticated control entity that can provide a simpler interface, for example automatically recovering state from a previous connection as is done with HTTP sessions.
Gliffy Diagram |
---|
size | L |
---|
name | Seperate Control Interface Lifcycle |
---|
align | center |
---|
version | 3 |
---|
|