From b45c84c24854c7aefccdd13bbd07de30cff12be1 Mon Sep 17 00:00:00 2001 From: Kaleb Elwert Date: Thu, 15 Oct 2020 01:28:55 -0700 Subject: [PATCH 1/4] SB-2 (Pluggable Transport): initial commit --- SB-2.md | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 SB-2.md diff --git a/SB-2.md b/SB-2.md new file mode 100644 index 0000000..2e4503b --- /dev/null +++ b/SB-2.md @@ -0,0 +1,89 @@ +# SB-2 (Pluggable Transport) + +**Status**: Under Review + +This proposal aims to introduce a pluggable transport to seabird-core and +introduce an alternative to gRPC. + +## Context + +All of the seabird APIs have been built around gRPC and protobufs. This is a +format which is backed by Google for RPC servers and includes code for client +and server autogeneration. Protobufs have a number of rough edges because of the +various limitations. However, even though this works fairly well for +server-to-server communication, it still falls short for web applications. + +## Dependencies + +- SB-1 (AMQP Backed Implementation) - SB-2 can be completed + without SB-1, but it would be much easier to do this after there's a simpler + implementation. + +## Goals + +- Introduce a new transport +- Allow multiple transports to be running at once, selectable by the backend or + plugin. +- Continue to be backwards compatible + +## Unsolved Problems + +- How to best handle bidirectional streaming/chat ingest + +## Details + +The main complication with other transports relates to bidirectional streaming. +Currently, the only APIs which use bidirectional streaming are the chat +backends. Because most users only implement plugins, it may be acceptable to add +additional complexity there and drop bidirectional streaming. + +### Data Format + +In general, either JSON (with `application/json`) or msgpack (with +`application/msgpack`) should be used for the serialization/deserialization. + +#### Replacing anyof + +Essentially, anyof is a tagged union. The simplest way to decode this in Go is +to have a wrapper struct with `type` and `payload` with the `payload` being a +`json.RawMessage`. Some msgpack libraries have an alternative to this. With +minimal glue, it should be possible to create a `RawJsonOrMsgpackMessage` which +would let us deserialize to either type trivially. Unfortunately, this also +means a two-step encoding process, so additional wrappers would need to be +written. + +For rust, serde supports tagged unions out of the box with `#[serde(tag = +"type", payload = "payload")]`. + +### Endpoints + +#### Request/Response + +Most endpoints are fairly straight-forward. Request-response over HTTP will +react fairly similarly no matter if you're using the data format in this +proposal or gRPC/protobufs. + +#### Chat Ingest + +Because Chat Ingest is bidirectional, it doesn't cleanly map onto HTTP. + +Thankfully there are other options: +- websockets (which require server support and +additional wrappers for reading auth from query params but support web cleanly +and matches the current paradigm) +- HTTP Multipart (which also requires some +additional wrappers to properly support streaming the form data) +- HTTP/2 (which +requires server support and has relatively limited library support, especially +on the frontend) +- HTTP/1.1 chunked encoding (though this would require having +additional ingestion endpoints as it would only be usable for events streaming +from the server). + +See https://github.com/twitchtv/twirp/issues/3 + +#### Event Stream + +Because the event stream is only reading events (and not bidirectional), it will +also map onto the same pattern as chat ingest, but without the additional work +to support sending events. From 8befe3232e4f94d8d7e95955dc4818d3b36bb55f Mon Sep 17 00:00:00 2001 From: Kaleb Elwert Date: Sat, 17 Oct 2020 02:02:09 -0700 Subject: [PATCH 2/4] SB-2: add reference to SB-3 --- SB-2.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/SB-2.md b/SB-2.md index 2e4503b..ce9a692 100644 --- a/SB-2.md +++ b/SB-2.md @@ -15,9 +15,11 @@ server-to-server communication, it still falls short for web applications. ## Dependencies -- SB-1 (AMQP Backed Implementation) - SB-2 can be completed - without SB-1, but it would be much easier to do this after there's a simpler - implementation. +- [SB-1 (AMQP Backed Implementation)](./SB-1.md) - SB-2 can be completed + without [SB-1](./SB-1.md), but it would be much easier to do this after + there's a simpler implementation. +- [SB-3 (API Refactor)](./SB-3.md) - this refactor would allow us to only + support server streams and would simplify this implementation more. ## Goals @@ -26,9 +28,12 @@ server-to-server communication, it still falls short for web applications. plugin. - Continue to be backwards compatible -## Unsolved Problems +## Potential Problems - How to best handle bidirectional streaming/chat ingest + - The current plan is to use HTTP/1.1 Chunked Encoding (or another similar + technology) once the API only requires server streaming and not ingestion + streaming. ## Details From 6d33742979cd10b83b241482af3b9a5e77f326e6 Mon Sep 17 00:00:00 2001 From: Kaleb Elwert Date: Wed, 21 Oct 2020 14:13:42 -0700 Subject: [PATCH 3/4] Add SSE as an option --- SB-2.md | 1 + 1 file changed, 1 insertion(+) diff --git a/SB-2.md b/SB-2.md index ce9a692..1ab2dd3 100644 --- a/SB-2.md +++ b/SB-2.md @@ -84,6 +84,7 @@ on the frontend) - HTTP/1.1 chunked encoding (though this would require having additional ingestion endpoints as it would only be usable for events streaming from the server). +- HTTP SSE (with newline delimited json events) See https://github.com/twitchtv/twirp/issues/3 From 234d716c8a70fda0f2954214255da3fe4fcd3d60 Mon Sep 17 00:00:00 2001 From: Kaleb Elwert Date: Wed, 21 Oct 2020 14:38:45 -0700 Subject: [PATCH 4/4] Update SB-2.md --- SB-2.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/SB-2.md b/SB-2.md index 1ab2dd3..17280a2 100644 --- a/SB-2.md +++ b/SB-2.md @@ -85,9 +85,15 @@ on the frontend) additional ingestion endpoints as it would only be usable for events streaming from the server). - HTTP SSE (with newline delimited json events) +- HTTP body streaming (with newline delimited json events) See https://github.com/twitchtv/twirp/issues/3 +Websockets and HTTP/2 are the cleanest way to get messages, though newline +delimited JSON would also work. Additionally websockets have fairly good browser +support. It gets more complicated for binary formats because you need to invent +a new container format. + #### Event Stream Because the event stream is only reading events (and not bidirectional), it will