theRAPTLab / gsgo

GEM-STEP Foundation repo migrated from GitLab June 2023
1 stars 1 forks source link

BUG: URSYS Message Behavior #30

Closed benloh closed 1 year ago

benloh commented 3 years ago

In GitLab by @daveseah on Mar 10, 2021, 15:15

This is an omnibus issue covering the following:

Background

In GEMSTEP, we expanded the message broker system to use channels, which allows us to further distinguish between types of messages and handle their routing more efficiently. This forces implementers to add the "scope" their messages and also keeps a single message namespace from becoming polluted.

In the past, URSYS made the distinction between local and network messages by using two APIs for messaging. Using NetSend() would send messages to remotes if any handlers existed, whereas LocalSend() would only send to handlers local to the issuing app.

As a result, there were six distinct commands:

LocalSend('MESG')           NetSend('MESG')
LocalSignal('MESG')         NetSignal('MESG')
LocalCall('MESG')           NetCall('MESG')

Changing to channel syntax reduces these to:

SendMessage('LOCAL:MESG')   SendMessage('NET:MESG')
RaiseMessage('LOCAL:MESG')  RaiseMessage('NET:MESG')
CallMessage('LOCAL:MESG')   CallMessage('NET:MESG')
---
Note: for local messages, you can leave off the `LOCAL:` prefix

In addition to LOCAL: and NET: channels, we have a utility channel * which is supposed to mean "send the message to all channels", but this has never been used in code prior to GEMSTEP.

Future channels are server specific, such as SRV: to replace the special NET:SRV_ message prefix that is used for all current server-implemented services. This will be more important when we have multi-server, cross-network messaging in place for later phases of GEMSTEP development. Since URSYS is "addressless", having server-specific channels will help with in-band message groups.

benloh commented 3 years ago

In GitLab by @daveseah on Mar 11, 2021, 22:14

After digging through a ton of code, I think the problem is that remote-to-remote call chains were never used by ANY apps. The first incarnation that used the system was PLAE/iSTEP, and NetCreate and MEME codebases all happened to use the version of the call that was server-only. So this feature may have been broken for an indeterminate length of time.

In any case, we don't need to fix it now, so I'm punting this until it actually needs to happen. The input system doesn't rely on it even in the prototype stage, because we can let the server broker the data as it has before. Remote-to-remote calls might have been useful for getting targeted state updates from a specific client, but for now we will use a more general model.

benloh commented 3 years ago

In GitLab by @daveseah on Mar 11, 2021, 22:40

TECHNICAL DISCOVERY NOTES

This applies only to CallMessage. SendMessage and RaiseMessage are fine.

When an calls another remote, the following happens:

The broken part is the correct detection and handling of a forwarded packet by the remote. There are several flags that are set that are supposed to help the message routers determine what to do, but this has been complicated by the addition of CHANNELS and it appears to have broken the logic.

Solution: rediagram the packet flow and fix the flagging system. Things to remember:

benloh commented 3 years ago

In GitLab by @daveseah on Mar 15, 2021, 10:03

CURRENT BEST PRACTICE for URSYS MESSAGING

I thought it would be useful to explain why we haven't needed the remote-to-remote call lately. It's due to a change in how we structure the relation between data, gui update, and gui entry.

PROBLEM ONE: DATA MANAGEMENT

In the earliest versions of STEP, our first Javascript prototypes were designed to talk to the server via a websocket, but each service needed its own API method and custom coding on both clients and server. This was slow to implement and more difficult to understand because each feature used its own logic.

UNISYS, the precursor to URSYS, was a messaging system that allowed us to define messages on-the-fly, defining a standard use pattern of (message, callback) for defining a receiver and (message, data) for requests. This made it much easier for developers to pass data to and from any computer on the network.

However, the connection between data updates and gui updates ("data binding") was still fragile because of the lack of an established pattern to follow.

PROBLEM TWO: SYNCHRONIZING GUI WITH DATA MANAGEMENT

We are now using React for our front end, so called because it "reactive" to changes in data flow. It is a popular framework, which makes it a good choice to make the STEP codebase accessible to a broad pool of developers.

There are two complications we have seen:

CURRENT PRACTICE

Current STEP now follows these practices using URSYS:

RAMIFICATION for URSYS

Because we're using this model, we no longer need to use remote-to-remote message calls as we did with some early versions of STEP. All of our operations now go to the server, which broadcasts data changes to all subscriber apps on the network, and each subscriber then uses that data to change React internal state so the GUI rerenders.