-
Notifications
You must be signed in to change notification settings - Fork 6
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
[protocolv2] Half-close client #162
Conversation
Test will fail miserably as I deferred fixing them to the server implementation |
54f5a03
to
f52f04c
Compare
f52f04c
to
54e6719
Compare
import { Value } from '@sinclair/typebox/value'; | ||
import { PayloadType, ValidProcType } from './procedures'; | ||
|
||
type RPCFn< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
type RPCFn< | |
type RpcFn< |
rust brain moment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HTML or Html, URL or Url? 🤷
lol i'll change it on the base branch
} | ||
|
||
if (!Value.Check(ControlMessageCloseSchema, msg.payload)) { | ||
if (Value.Check(AnyResultSchema, msg.payload)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
completely unrelated to this pr but could be cool to do compiled versions of common schema checks:
https://github.com/sinclairzx81/typebox#typecheck-typecompiler
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah great idea.
infer __UploadInputMessage, | ||
infer UploadOutputMessage, | ||
(...args: never) => Promise<infer UploadOutputMessage>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
o damn nice
: never | ||
: Procedure extends object & { stream: infer StreamHandler extends Fn } | ||
? Awaited<ReturnType<StreamHandler>> extends [ | ||
? ReturnType<StreamHandler> extends [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still weird that some procedure constructors are async and others aren't but maybe thats fine 🤷
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's just Rpc that returns a promise
All the changes are documented in `Protocol.md` but here's a summary: - Handle invalid client requests by sending a close with an error back - This was the main motivation for the change. While we could sort-of implement this error response without the other changes, things are setup in such a way where it is very hard to implement correctly without deeper changes in how we handle closing. - Add more robust closing mechanics - Half-close states - Close signals from read end of the pipes - Abort full-closure (for errors and cancellation) - Switch from `Pushable` and `AsyncIterator` APIs to a `ReadStream` and `WriteStream` - All procedures have `init` and some have `input` While the changes are not strictly backwards compatible, hence the major protocol bump, the system can still operate across versions to some extent. See PRs linked below for more information on the above # TODOs - [x] Define protocol and update doc #111 - [x] Design stream abstractions #118 - [x] Redsigned in #249 - [x] Implement stream abstractions - [x] ReadStream #130 - [x] WriteStream #132 - [x] All streams have init, some have input. - [x] Protocol change documented in #153 - [x] Implementation change #159 - [x] Use stream abstractions & implement protocol closing semantics - [x] Protocol: Implement close requests from readers #165 - [x] Protocol: Implement half-close - [x] Client #162 - [x] Server #163 - [x] Simple s/Pushable/Stream replacement - [x] Client #136 - [x] Server #137 - [x] Make `Input` iterator on the server use `Result` so we can signal stream closes, client disconnects, and aborts #172 - [x] Add Abort mechanism - [x] Docs update #175 - [x] Implement abort - [x] Client #193 - [x] Server #200 - [x] Add `INVALID_REQUEST` to schema #107 - [x] Handle/send back `INVALID_REQUEST` errors with an abort bit #203 - [x] Handle/send back `INTERNAL_RIVER_ERROR` with an abort bit #203 - [x] Send abort bit with `UNCAUGHT_ERROR` #201 - [x] Abort tombstones #204 - [ ] Try to find uncovered areas to test - [ ] `undefined` value for `init`, `input`, & `output`. - [ ] Update docs - [ ] Changelog --------- Co-authored-by: Jacky Zhao <[email protected]>
Why
Starting to implement half-close semantics, this targets the client side. Please read Protocol.md in #127 to understand what's going on.
What changed
stream
returns an[inputWriter, outputReader]
tupleupload
returns an[inputWriter, finalizerFn]
tuple, wherefinalizerFn
returnsPromise<OutputResult>
subscription
returnsoutputReader
rpc
returnsPromise<OutputResult>
createProcStream
works on the server), and then construct the return interface.rpc
sendsCloseBit
andOpenBit
as part ofinit
is an optional thing, and would work for other types of procs if we want. In theory, withrpc
you can send init with anOpenBit
only and then send aCloseControl
message as a follow. In a more extreme world, yourstream
can sendCloseBit
andOpenBit
as part ofinit
which instantly closes theinput
(client-to-server) stream. We might want to updateProtocol.md
to indicate that all types of procedures work the same way, and things likerpc
sending open and close in one message is just an optimization.CloseBit
withinit
, since we don't need theinput
stream.