QuinnRPC
Created on 2024-01-24T11:05:46-06:00
Note: I came up with this before realizing it depends on a reliable transport (TCP, QUIC.) You would have to take extra steps to make it work with unreliable transports.
Wire format
Built on top of a standard Thrift/Protobuf-like wire format with a single addition.
We add a "variable reference" data type. This says the real value can be found at a given offset of an array of slots.
Smalltalk inspiration
Objects: Objects are something that exist and you can send messages to it.
Keywords: Keywords are identifiers of parameter names and end with a colon.
Messages
You send a 'message' to an 'object' identified by a 'selector'.
Selectors
Selectors identify a handler for a message.
Messages with parameters have one keyword for each parameter.
Keywords are collected to form the message's name such as "send-message:to-player:"
Unary messages have only a single identifier for a name.
Responses
Caller specifies if return values should be ignored, placed in local storage at a given index, or sent back asynchronously.
Local variable storage
An array of some pre-agreed upon number of slots which can hold objects.
These are initially "nil" until a value is deposited there.
Local storage is used to hold the output of previous commands and refer to those outputs symbolically. This is what allows us to queue up an entire "chain" of calls and responses in a single round-trip.
Message chains
Each chain gets a single instance of local value storage.
A chain is basically an array of message sends.
Parameters to message sends may be a "local value reference," which says to get the value from there instead of the packet being sent.
Server processes the chain of events before responding.
We can ask that values be put in local storage. Like JMAP we can chain together requests to whittle down the actual response that we want.
Inspirations
-
TODO link not implemented: => Smalltalk-80TODO link not implemented: => JMAPTODO link not implemented: => GraphQLTODO link not implemented: => DeepR