diff --git a/docs/protocol/2.networking.md b/docs/protocol/2.networking.md deleted file mode 100644 index d997a49e7..000000000 --- a/docs/protocol/2.networking.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -id: networking -title: Networking ---- - -The Skyhash protocol uses a very simple data exchange model. It makes use of three connection stages: - -- **Client handshake**: The client sends a handshake packet - - The handshake contains all necessary information to successfully establish a connection - - The structure of the client handshake depends on the authentication plugin in use (since authentication data has to be exchanged before the connection can be established) - - For the `pwd` plugin the client handshake looks like this (split into lines for convenience): - ``` - H0 - - 000 - \n\n - ``` - > For the protocol compatibility code, [see the version matrix](.#version-matrix) -- **Server handshake**: - - **Accepted:** If the server accepts the handshake information then it will respond with: `H000` - - **Rejected**: If the server rejects the handshake information then it will respond with `H01<8-bit error code>`. You can find out what happened using [the error code index](errors) -- **Data exchange**: This is where the client and server exchange data - -How to communicate: -- Open a TCP connection to the server -- Do the handshake (as described above) and handle any errors -- Encode queries as described below - -:::tip Is my client compatible? -If the server has accepted your connection then you can be sure that the protocol version and other extensions that your client intends to use is supported by the server. If this isn't the case, then the server will respond with a handshake error code indicating why the connection was rejected. [See all the handshake error codes here](errors#handshake-errors). -::: - -## Client - -### Data types - -The client side needs to send encoded data types to the server (in the form of parameters) so that the server can process them. - -Types: -- Null: Encoded as `0` -- Bool: Encoded as `1<0 or 1>\n` -- Unsigned integer: A 64-bit unsigned integer. Encoded as `2\n` -- Signed integer: A 64-bit unsigned integer. Encoded as `3\n` -- Float: A 64-bit (double precision) floating point value. Encoded as `4\n` -- Binary: A binary blob. Encoded as `5\n` -- String: An UTF-8 string. Encoded as `6\n` - -### Queries - -A query has three sections: -- The metaframe: - - Contains metadata about the query - - Encoded as: `S\n` (total size of the other two sections) -- The dataframe header: Encoded as `\n` -- The dataframe: - - First part contains the query body, encoded as: `` (the query body is simply appended here) - - Second part contains the payload body with all the parameters, encoded end-on as: `...` (repeat for all parameters). See [the data types for parameters above](#data-types). - -## Server - -### Data types - -The server will respond with different data types, depending on the context. These include: -- Null: Encoded as `0` -- Bool: encoded as `1<0 or 1>\n` -- Unsigned integers: - - First byte: 2 -> 8-bit, 3 -> 16-bit, 4 -> 32-bit, 5 -> 64-bit - - Payload: `\n` -- Signed integers: - - First byte: 6 -> 8-bit, 7 -> 16-bit, 8 -> 32-bit, 9 -> 64-bit - - Payload: `\n` -- Simple collections: - - First byte: 10 -> binary, 11 -> string - - Payload: `\n` -- Complex collections: - - First byte: 11 -> list - - Payload: `\n` - -### Responses -The server can respond with any of the data types [above](#data-types-1), or it can respond with a special response type like these: - -- **Error**: Encoded as `0x10<16-bit error code>` -- **Row**: The server has returned a row. Encoded as `0x11\n` -- **Empty**: This indicates that the query ran successfully but nothing appropriate can be returned (like HTTP's 200 status). Encoded as `0x12` -- **Multirow**: The server has returned multiple rows. Encoded as `0x13\n` diff --git a/docs/protocol/3.errors.md b/docs/protocol/errors.md similarity index 96% rename from docs/protocol/3.errors.md rename to docs/protocol/errors.md index cbfa32a34..39507af03 100644 --- a/docs/protocol/3.errors.md +++ b/docs/protocol/errors.md @@ -1,9 +1,9 @@ --- id: errors -title: Errors +title: Error Index --- -If you've done something incorrectly, then the server will respond with an error code (just like HTTP status codes, but note that the server will not respond with an error code if no error occurred, unlike HTTP 200!). +This document provides an exhaustive listing of all the error codes that can be returned by the server. Do note that the [handshake errors](#handshake-errors) are only returned in the *connection stage* and are not the same as the [query errors](#query-errors) which occcur at the *exchange* stage. ## Handshake errors diff --git a/docs/protocol/index.md b/docs/protocol/index.md index b27a358ec..7c30eea3c 100644 --- a/docs/protocol/index.md +++ b/docs/protocol/index.md @@ -28,12 +28,13 @@ Here are some good to know things, before a deep dive into the various pieces of - the queries sent by an older client can't be processed by the server or - the **same** responses sent by *the server in question* can't be decoded by the older client - If newer protocol versions introduce newer data types that is *not* considered an incompatible version since as long as the encoding for the types introduced in the earlier protocol(s) remains unchanged +- Hence, the compatibility code for a protocol only changes when it is considered incompatible ### Version matrix Please note this list is only maintained post 0.8.0. -| Server version (release tag) | Skyhash Version | Compatibility Code | Notes | -| ---------------------------- | --------------- | ------------------ | ---------------------------- | -| 0.8.0 | 2.0 | `0` | Initial release of Skyhash/2 | -| 0.8.1 | 2.0 | `0` | | +| Server version (release tag) | Skyhash Version | Compatibility Code | Notes | +| ---------------------------- | --------------- | ------------------ | ----------------------------------- | +| 0.8.0 | 2.0-beta | `0` | Initial release of Skyhash/2 (beta) | +| 0.8.1 | 2.0-beta | `0` | | diff --git a/docs/protocol/specification.md b/docs/protocol/specification.md new file mode 100644 index 000000000..6b6fb6742 --- /dev/null +++ b/docs/protocol/specification.md @@ -0,0 +1,103 @@ +--- +id: specification +title: 'Specification' +--- + +# Skyhash 2: Specification + +## Network layer + +As noted earlier, Skyhash is a client/server protocol built on top of TCP, that enables communication between a Skytable database server and a Skytable client. The Skyhash protocol uses a very simple data exchange model with the following three connection stages: + +- Connection stage: + - **Client handshake**: The client sends a handshake packet + - The handshake contains all necessary information to successfully establish a connection + - The structure of the client handshake depends on the authentication plugin in use (since authentication data has to be exchanged before the connection can be established) + - For the `pwd` plugin the client handshake looks like this (split into lines for convenience): + ``` + H0 + + 000 + \n\n + ``` + > For the protocol compatibility code, [see the version matrix](/protocol/#version-matrix) + - **Server handshake**: + - **Accepted:** If the server accepts the handshake information then it will respond with: `H000` + - **Rejected**: If the server rejects the handshake information then it will respond with `H01<8-bit error code>`. You can find out what happened using [the error code index](errors) +- Data exchange stage: This is where the client and server send and receive data. A client and server will spend the majority of their time in this stage. +- Termination stage: Once the connection is no longer needed, the client (or in exceptional cases, the server) will close the connection using a simple TCP FIN. + +:::tip Is my client compatible? +If the server has accepted your connection then you can be sure that the protocol version and other extensions that your client intends to use is supported by the server. If this isn't the case, then the server will respond with a handshake error code indicating why the connection was rejected. [See all the handshake error codes here](errors#handshake-errors). +::: + +### Exchange modes + +The Skyhash/2.0 specification defines the following exchange mode: +- **Query-time**: This works like a request/response action where the client sends a request and the server responds with a response to the query (or an error) + +Expect other exchange modes (bi-directional) to be added in future protocol revisions. + +## Query-time exchange + +In query-time exchange, the protocol works like a "request-response" action where queries are sent by the client and the server sends a repsonse. Queries can be simple queries or pipelines (specification to be finalized[^1]). + +### Client data types + +The client side needs to send encoded data types to the server (in the form of parameters) so that the server can process them. The following types are defined: +- Null: Encoded as `0` +- Bool: Encoded as `1<0 or 1>\n` +- Unsigned integer: A 64-bit unsigned integer. Encoded as `2\n` +- Signed integer: A 64-bit unsigned integer. Encoded as `3\n` +- Float: A 64-bit (double precision) floating point value. Encoded as `4\n` +- Binary: A binary blob. Encoded as `5\n` +- String: An UTF-8 string. Encoded as `6\n` + +> **Note**: A `` is the value of the length in question converted to an ASCII string. + +### Server data types + +The server will respond with different data types, depending on the context. The following types are defined: +- Null: Encoded as `0` +- Bool: encoded as `1<0 or 1>\n` +- Unsigned integers: + - First byte: 2 -> 8-bit, 3 -> 16-bit, 4 -> 32-bit, 5 -> 64-bit + - Payload: `\n` +- Signed integers: + - First byte: 6 -> 8-bit, 7 -> 16-bit, 8 -> 32-bit, 9 -> 64-bit + - Payload: `\n` +- Simple collections: + - First byte: 10 -> binary, 11 -> string + - Payload: `\n` +- Complex collections: + - First byte: 11 -> list + - Payload: `\n` + +> **Note**: A `` is the value of the length in question converted to an ASCII string. + +### Simple query/response + +#### Simple query + +A simple query sends a single BlueQL query to the server to which the server responds with a [simple response](#simple-response). It has three sections: +- The metaframe: + - Contains metadata about the query + - Encoded as: `S\n` (total size of the other two sections) +- The dataframe header: Encoded as `\n` +- The dataframe: + - First part contains the query body, encoded as: `` (the query body is simply appended here) + - Second part contains the payload body with all the parameters, encoded end-on as: `...` (repeat for all parameters). See [the data types for parameters above](#client-data-types). + +#### Simple response + + +When the client sends a [simple query](#simple-query), the server will respond with a simple response using any of the [response data types](#server-data-types), or it can respond with any of the following response structures: + +- **Error**: Encoded as `0x10<16-bit error code>` +- **Row**: The server has returned a row. Encoded as `0x11\n` +- **Empty**: This indicates that the query ran successfully but nothing appropriate can be returned (like HTTP's 200 status). Encoded as `0x12` +- **Multirow**: The server has returned multiple rows. Encoded as `0x13\n` + +> **Note**: A `` or `` is the value of the length in question converted to an ASCII string. + +[^1]: See the [discussion here](https://github.com/skytable/skytable/issues/332) diff --git a/docusaurus.config.js b/docusaurus.config.js index 222d51cb6..c5d9136bf 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -157,6 +157,10 @@ module.exports = { { from: '/protocol/overview', to: '/protocol' + }, + { + from: '/protocol/networking', + to: '/protocol/specification' } ] }] diff --git a/sidebars.ts b/sidebars.ts index 6a5ebe714..9b1e3f9a3 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -48,7 +48,7 @@ module.exports = { label: 'Protocol', items: [ "protocol/index", - "protocol/networking", + "protocol/specification", "protocol/errors" ], },