Re: Message Broker Architecture
From: H. S. Lahman (h.lahman_at_verizon.net)
Date: 07/10/04
- Next message: Isaac Gouy: "Re: Static vs. Dynamic typing (big advantage or not)---WAS: c.programming: OOP and memory management"
- Previous message: Phlip: "Re: use cases and reuse"
- In reply to: Mikhail Kimmelman: "Re: Message Broker Architecture"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Sat, 10 Jul 2004 15:40:20 GMT
Responding to Kimmelman...
>>Let's see if I understand this correctly. The actual messages are the
>>same so far as the legacy code is concerned. In effect you are
>>replacing a local client with a subsystem that can talk to a remote
>>client. The subsystem's only responsibility is format conversions. Is
>>that correct?
>
>
> Yes, but not exactly. Another responsibility is to manage communication
> with remote clients.
>
> Let's assume also that remote clients use TCP sockets. Thus that subsystem
> should listen for connections, manage socket connections etc.
IOW, you are going from:
+-----------------+
| Legacy System |
| +------+ +--------------+
| | I/O |<----------->| Local Client |
| +------+ +--------------+
| |
| +------+ +--------------+
| | I/O |<----------->| Local Client |
| +------+ +--------------+
| |
~ ~
| |
+-----------------+
where the legacy system manages the threading of clients, to:
+-----------------+
| Legacy System |
| +------+ +--------------+
| | I/O |<----------->| Local Client |
| +------+ +--------------+
| |
| +------+ +--------------+
| | I/O |<----------->| Local Client |
| +------+ +--------------+
| |
| +----------+ +--------------+
| | new |<----------->| Remote Client|
| | |<--------+ +--------------+
| | I/O |<----+ |
| +----------| | | +--------------+
| | | +-->| Remote Client|
+-----------------+ | +--------------+
|
| +--------------+
+------>| Remote Client|
+--------------+
where your "new I/O" manages threading for sockets and network
protocols, converts the messages into legacy format, and them internally
routes those messages to the old I/O ports so that the legacy code
thinks the remote clients are local.
However, you comments about not wanting to change the legacy server
below suggest that you want to create another local process rather than
a subsystem in the legacy server. That would move "new I/O" out:
+-----------------+
| Legacy System |
| +------+ +--------------+
| | I/O |<----------->| Local Client |
| +------+ +--------------+
| |
| +------+ +--------------+
| | I/O |<----------->| Local Client |
| +------+ +--------------+
| |
| +------+ +---------------+
| | I/O |<------>| new |
| +------+ | I/O +-----+ +---------------+
| | | | skt |<------>| Remote Client |
| +------+ | +-----+ +---------------+
| | I/O |<------>| |
| +------+ | +-----+ +---------------+
| | | | skt |<------>| Remote Client |
| | | +-----+ +---------------+
~ ~ ~ ~
| | | |
+-----------------+ +---------------+
Basically the new process pretends it it a group of local clients from
the legacy server view. FWIW, I like this configuration much better
because there is no risk of network protocol threads stepping on client
processing threads.
>
>
>>>The broker implements both the legacy protocol to communicate
>>>with the legacy server as a local client and and new protocols to
>>>communicate with new remote clients.
>>>
>>>The broker is a multi-threaded process, designed as follows:
>>
>>Why multi-threaded? It seems like a lot depends on how the legacy code
>>currently talks to a local client. I assume the legacy already deals
>>with threading due to the possibility of multiple local clients. If
>>that is the case, then the local client is single-threaded relative to
>>the legacy code.
>
>
> The legacy server knows how to deal with multiple clients. However it does not
> know how to handle multiple socket connections, for example. So, it is up to the
> broker to handle all that socket stuff (in this particular case we could use
> multiplexing
> instead of multi-threading but it is irrelevant to our discussion).
OK. I was just pushing back with the idea that one should resort to
threading only when one must to resolve nonfunctional requirements. For
example, if all one needs to worry about is socket resource allocation,
then one can serialize with an event queue manager(s) and a
semaphore(s). That will usually be less overhead than using OS
threading facilities that have to provide infrastructure for instruction
level time slicing.
>
> > That presents an interesting possibility. One can simply link in a
>
>>subsystem to talk to a remote client that plugs into the same legacy
>>hook that a local client plugged into. In that case, the remote client
>>would appear to be a local client to the legacy code.
>
>
> Do you mean to "add" some code to the legacy server ?
Yes, a subsystem that would accept network messages from remote clients
(i.e., the middle example above).
>
> Sincerely I do not know if it is possible, but I do not want to start talking
> with
> my management about exposing the legacy server to remote clients and
> changing anything in the legacy server
In that case, one is left with the separate process approach in the
third example above. B-)
>
> [..]
>
>
>>That separation of concerns is good. However, you may be able to do
>>even better (assuming my simplistic suggestion about can't work in your
>>situation)...
>>
>>where Send/Receive are part of the same interface Facade but provide
>>separate encode/decode. Only those interfaces understand the local
>>platform semantics and all they do is encode/decode messages. These
>>Facades are equivalent to your Hosts.
>>
>>On the legacy server side the Dispatcher is the equivalent of your
>>Message Broker. It understands the legacy server issues for concurrency
>>and whatnot. It stands between the client interface Facade and the
>>actual legacy code that does something useful with the messages. So it
>>incorporates your Message Handler facilities.
>>
>>Note that now there is no logical distinction between a remote client
>>and a local client. The local client just has a different Send/Receive
>>facade that is linked in to talk directly to the server's Send/Receive
>>interface facade rather than over a network.
>>
>>In addition, the inter-platform network can be isolated through reusable
>>modules shared in each Send/Receive facade. IOW, everybody talks to the
>>same network protocol regardless of what the local platform processing
>>is to get to the port. They just encode/decode for different contexts.
>> This makes life simpler on the server side because it is completely
>>decoupled from the remote platforms.
>
>
> It is really nice, but I am afraid you assume here, that I may change the legacy
> server code. Unfortunately I may not.
The same basic principles apply to the separate process. Its interfaces
provide the same sorts of Facades.
[In my world, a subsystem /always/ has highly disciplined event-based
interfaces with by-value data packets in the OOA/D. So it could be
distributed without change by simply providing the correct
infrastructure calls at the OOP level when sending/receiving events.
IOW, it doesn't matter to the subsystem and its interfaces whether it is
linked in directly, it is in a separate DLL, or has has a main() wrapper
around it.]
To get back to your original post's question, I think your basic idea is
correct. But I am a little concerned about linking the semantics of the
messages to the network protocol formats.
It seems to me that the message processing (i.e., format related) should
be trivial. Whether a client is local or remote, I would expect the
messages to have exactly the same semantics. That is, the remote
clients send/receive the same messages as local clients. Those
messages, though, need to be reformatted cosmetically for the network
data packets. That should be a reusable module across all the "hosts".
Unless you are sending binary data in the message packet, that should
not be much of a problem. The semantic portion of the message is then
just a pass-through, regardless of network protocols. Is binary data
sent in the original local client messages?
In your original post you mentioned posix and MFC in the same breath,
which seemed puzzling since they are at different levels of abstraction.
It seems to me each remote client has a rather simple task: it formats
a message and sends it to its local network port. While
platform-dependent, that is usually fairly straight forward by today's
standards so long as the application isolates the network interactions
within a subsystem. The remote clients need to know nothing about the
legacy server, other than its identity and network location.
Only the Dispatcher on the legacy server platform is special because it
also has to manage the mapping of multiple sockets to "local clients".
But it has that same simplistic message encoding/decoding because it is
also just talking to a network port and the message semantics remains
the same as it was on the remote hosts.
The point I am getting at here is that the message processing should be
quite mechanical and should not depend on the actual semantics of the
message content. Basically all one has is:
{message ID, data} // local client format on Host A
1 |
| encode
|
* V
{network stuff, message ID, data} // network message format
* |
| decode
|
1 V
{message ID, data} // local client format on Host B
It doesn't matter whether Host A is the server, a local client, or a
remote client. Similarly, it doesn't matter which of those Host B is.
The only semantics required for the encode/decode is at the data field
level (length, type, etc.). Each host gets to interpret the data
semantically from the existing local client format and it does that
through the message ID.
That allows exactly the same encode/decode module to be used on each
host. More important, it completely decouples the hosts because they
only interpret the messages in their own context and they all just talk
to a network port.
*************
There is nothing wrong with me that could
not be cured by a capful of Drano.
H. S. Lahman
hsl@pathfindermda.com
Pathfinder Solutions -- Put MDA to Work
http://www.pathfindermda.com
(888)-OOA-PATH
- Next message: Isaac Gouy: "Re: Static vs. Dynamic typing (big advantage or not)---WAS: c.programming: OOP and memory management"
- Previous message: Phlip: "Re: use cases and reuse"
- In reply to: Mikhail Kimmelman: "Re: Message Broker Architecture"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|