Replies: 3 comments 2 replies
-
Dropping Regarding header changes, I think this is not justified in the form stated here. On the contrary, I would gather all the parameters that has to be submit back and compared into a single "dictionary". I.e. we could split "headers" into "metadata" and "extensions". Adding individual struct fields "to the end of the message" is weird in such places as Also current approach is a little bit lazy on our side as we don't keep backwards compatibility in the protocol at client side. As long as we start doing that, adding features such as capabilities is much easier to do by negotiating "extension" at the handshake and using header for new thing, instead of bumping protocol version. Or even if we do bump version, supporting extra header is easier than extra field presence of which depends on message length and protocol version. |
Beta Was this translation helpful? Give feedback.
-
Here are a couple of things I think worth investing into instead:
|
Beta Was this translation helpful? Give feedback.
-
Another thing left on my to do list is idle timeouts and pings. If you still want pings come from clients, then we have to announce timeout in server-side handshake (and enforce it). |
Beta Was this translation helpful? Give feedback.
-
Headers & Message Layout
Our binary protocol message structure is inherited from PostgreSQL. The motivation for that is to avoid repacking data messages coming from Postgres to our own format. Back when we designed the very first version of our protocol we made a decision to add "headers" to basically all protocol messages. The intention was to use headers to include auxiliary data, like tracing & debug information. We could introduce such headers without requiring all clients to bump the protocol version.
At some point, however, we started to abuse the message headers, adding headers that can change the output structure, control what capabilities the query is allowed to use, etc. That blurs the difference between headers & message fields and makes both the client and the server code unnecessarily messy. Most importantly, we still had to bump the protocol version and change the parsing logic with every new header we've introduced so far. And lastly, headers use their own ad-hoc value serialization format, different from the rest of the protocol.
I propose to:
Fold the following headers into message fields:
ALLOW_CAPABILITIES
,IMPLICIT_LIMIT
,IMPLICIT_TYPENAMES
,IMPLICIT_TYPEIDS
,EXPLICIT_OBJECTIDS
.Declare that we never again use headers for purposes other than sending auxiliary data (such as metrics and debug information).
When adding new capabilities to existing protocol messages we will add them as message fields to the end of the message, bumping the protocol version.
While we are there, the
CommandComplete
message does not need theCAPABILITIES
header. Instead,OptimisticExecute
must have thecapabilities
field, which must be matched against the cached query.For example, this is what we have now:
And this is what we should have:
Drop
ExecuteScript
. Enhance theParse
/Execute
Flow.Historically, our
ExecuteScript
message was based on Postgres'SimpleQuery
, basically inheriting all of its warts to this day:Over the course of working with the protocol it became apparent that the right solution would be to simply allow our
Prepare
andOptimisticExecute
messages to accept EdgeQL scripts. Scripts will have some limitations:Other than that, we can implement the very similar flow we have for regular commands with
Prepare
/Execute
andOptimisticExecute
. BothPrepare
andOptimisticExecute
will get a new boolean field:script_mode
, which when set would allow them to accept a sequence of commands.Backwards Compatibility
Let me state the obvious: the first part of this proposal will be somewhat painful to implement. We'll have to update all of our binding libraries (JS, Python, Go) and our CLI. The protocol version will have to be bumped. The server-side protocol parsing code will blow up in size as we'll have to support both the old protocol and the new protocol for at least one version.
The second part of the proposal, however, does not have any backwards compatibility issues. Drivers will stop using the deprecated
ExecuteScript
message and allow users to pass arguments to their scripts (a new feature). As for script-mode restrictions, we already implement them inExecuteScript
.Beta Was this translation helpful? Give feedback.
All reactions