JKISoftware / JKI-State-Machine-Objects

Object-oriented framework for LabVIEW based on the JKI State Machine
BSD 3-Clause "New" or "Revised" License
96 stars 55 forks source link

[Discussion] Asynchronous Messaging #26

Open francois-normandin opened 7 years ago

francois-normandin commented 7 years ago

This is a thread to continue two related discussions here and here on the topic of asynchronous messaging to be supported or not in SMO base.

francois-normandin commented 7 years ago
francois-normandin commented 7 years ago

Request-Reply The public method sends a message to the process and does not wait for a response. The reply comes as a message which the caller receives through a notification mechanism (event, queue, notifier, etc.)

Request-Response The public method sends a message to the process and waits for up to a certain time (timeout) for a response to come back. The response is synchronous from the API's perspective.

drjdpowell commented 7 years ago

I was using the two terms differently (and quite possibly poorly, but here they are):

Request-Response: In response to receiving a message, I send another message, to someone that is previously specified.

Request-Reply: On receiving a message I reply to the message (i.e. to the reply address attached to the incoming message).

The key difference is that in the second it is the original requestor that directs where the replies go. It is entirely up to the Requestor if it blocks waiting for a reply, or provides an async notification mechanism, or even provides an “address” of a third party.

francois-normandin commented 7 years ago

Let me rephrase to see if I get your point correctly.

A depends on B and D, B depends on C. A requests info from B, and B redirects the request to C. Then C responds directly to A, which is the reply address? (Or A provided a reply address to D)

drjdpowell commented 7 years ago

A, assuming A attached its address to the message.

A requests info from B (attaching its address to the message). B forwards the message (with reply address still attached) to C for handling. C replies to the message, thus sending to A.

If, instead, C always responds to messages of this type by always sending something to A, then that isn’t a reply.

francois-normandin commented 7 years ago

OK, that's what I understood from your comment.

SMOs rely generally on public events for this type of (local) replies, where A subscribes to B and C's public events through a "Get Dependencies" reference. That does require that A knows about C, which is not optimal but works fine for most use cases. Complete decoupling can only be achieved through the example you describe. The reply approach also minimizes unnecessary traffic, which can be a boon for high-throughput apps. (and no need to have both A and B handle the event)

I'm curious how would you handle reply messages that need to go over the network to a different target? I'm thinking of providing an interface which would be agnostic to the transport layer (TCP, websocket, streams, Modbus, CAN, etc.). Any thoughts?

BTW, I'm still unclear if that should be in the base class...

drjdpowell commented 7 years ago

I have a youtube video on TCP with Messenger Library. TCP is handled by two actors running in them background: “TCP Connection” and “TCP client”. They alter the Reply Addresses of the messages they pass through so that the replies are routed back via them. So if A does Request-Reply to a remote B, the actual messages pass A—>TCPClient—TCP—>TCPConn—>B and Replies: B—>TCPConn—TCP—>TCPClient—>A

The Reply address on the message that B receives contains the address of TCPConn, along with a token that contains the address of A, which TCPClient reads when the reply gets to it.

francois-normandin commented 7 years ago

I'll check this out. We have an extension to the SMO base that abstracts transport layers but it is of the pub-sub / req-response variety. You get me thinking ;-)