-
Notifications
You must be signed in to change notification settings - Fork 42
RPC Proposal #177
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Posting this after internal discussion to open it for community comment. We have begun making progress on #173. |
I am not a big fan of As a developer if my method doesn't require arguments I would simply write |
Proposal updated |
Tracking of progress available here: https://github.com/RainwayApp/bebop/projects/2 |
From standup:
|
Added a wiki page to be an introduction |
maybe (Publisher/Subscriber and Callee/Caller) support ? |
Goals
Basic Features
Inspirations
Paradigm Decisions
(Bold items we plan to implement, non-bold items we considered).
Possible Features:
(Bold items we plan to implement, non-bold items we considered).
Schema
RPC introduces a new keyword
service
which allows defining a set of functions. Services have function definitions which express what data is expected and returned. They also define the opcode to function name mapping (names are used in the code, opcodes in the serialized form).Restrictions:
0
opcode is reserved forstring serviceName()
0xfff0-0xffff
opcodes are reserved for future usesDefinitions:
opcode
,name
,arguments
, andreturn
values. Both arguments and return types automatically defines astruct
. Generated code should strive to elide the argument/return wrapper structs as appropriate for the language.void
is a special return type which indicates no bytes and declares an empty struct.Protocol
The language-agnostic components which can be written in bebop.
Static Structures
These do not change based on the user schema and should be included in bebopc as a text string which can be generated on demand for the needed languages.
Headers
Null Service
This should be hardcoded and not be generated from static bebop, see Implementation.
Datagram
Dynamic Structures
These are not actually written in bebop syntax anywhere, however, the AST structure would be generated and used to produce the language-appropriate structures. So for readability they are presented here as bebop.
It is preferable to avoid using a
union
here because it would create either another layer ofsize
andopcode
on top of what is already present OR it would create a dependency between the static definition and the definitions for each and every service leading to significantly more code generation.Return structs don't strictly add a ton of value, but they make the code more symmetric and a little easier for the generator to spit out in theory. We may opt to remove them later. The same goes for empty argument structs with only zero or one items.
Standard Components
These can be hardcoded since they don’t change or have special code written to make them semi-dynamic and are the same for all services. This needs to be the same signature for all to allow cross-service name checks. This is the only function which should be guaranteed to work no matter what service is on the other end.
Signatures
Signatures are to to ensure the binary data sent between the peers is interpretable. It should not therefore include things which are changeable without altering the binary representation if at all possible.
We already ensure the sizes line up with what is expected; this is a good check for ensuring we don't end up reading invalid memory, but it is not enough to catch many possible errors. Using signatures means we can throw a signature error rather than a generic decode error. They are designed to catch human mistakes and prevent possible data corruption in a database. Signatures are not needed to ensure the protocol itself remains safe.
There are cases where we would have been able to correctly read the data even if the signature does not match such as if a new field is added to a union or a message since bebop is required to be forward compatible for both. There is a solution to this using composable hashes, but it is a feature we will need to revisit later if we decide it is needed.
The above example strings above are probably not what we will end up generating but do give the idea of what needs to be captured and one way it could be done. We may also want to include these raw signature strings as constants so they can be included in error messages.
Implementation
The language dependent components which connect with the generated code and make it function.
The following pseudocode is written in Rust as it is the most expressive of the languages we are using. The real implementation will be somewhat different as things come up. This is a template which hopes to set forth the logical structures and to pin down naming choices.
The bebop structs mentioned in the protocol section are assumed to be generated and will not be re-listed here.
Static Runtime
Building Blocks
Router
Error Handling
Implementations for Static Parts
These may be worth hardcoding rather than trying to implement by generating from static bebop.
Generated Code
This generated code is separate from what is currently created by bebop and cannot be made simply by leveraging the AST. In its implementation, it will reference types that were generated more classically and are described in protocol.
Service Definitions
User Code
The text was updated successfully, but these errors were encountered: