From 9933509804e836d1f393dedc5df8bd2ce27ce4b2 Mon Sep 17 00:00:00 2001 From: Vladimir Magamedov Date: Sun, 1 Apr 2018 04:30:40 +0300 Subject: [PATCH] Written about cancellation and deadlines into overview.rst --- docs/overview.rst | 59 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/docs/overview.rst b/docs/overview.rst index ac9458f..cca627a 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -30,14 +30,67 @@ level of extensibility as HTTP has. Messages are sent using one or several ``DATA`` frames, depending on maximum frame size setting and message size. Messages are encoded using simple format: prefix + data. Prefix contains length of the data and compression flag. You -can learn gRPC wire protocol in more details here: -`gRPC format `_. +can learn gRPC wire protocol in more details here: `gRPC format`_. gRPC has 4 method types: unary-unary, unary-stream (e.g. download), stream-unary (e.g. upload), stream-stream. They are all the same, the only difference is how many messages are sent in each direction: exactly one (unary) or any number of messages (stream). +Cancellation +~~~~~~~~~~~~ + +As it was said above, h2 allows you to cancel any stream without affecting other +streams, which are living in the same connection. And h2 protocol has special +frame to do this: RST_STREAM_. Both client and server can cancel streams. +This feature automatically gives you ability to proactively cancel gRPC method +calls in the same way. In ``grpclib`` you can cancel method calls immediately, +for example: + +- client sends request to the server +- server spawns task to handle this request +- client wants to cancel this request and sends ``RST_STREAM`` frame +- server receives ``RST_STREAM`` frame and cancels task immediately + +Most other protocols doesn't have this feature, so they have to terminate +whole TCP connection and perform reconnect for the next call. It is also not +obvious how to immediately detect terminated connections on the other side, +and this means that server most likely will continue result computations, when +this result is not needed anymore. + +Deadlines +~~~~~~~~~ + +Deadlines are basically timeouts, which are propagated from service to service, +to meet initial timeout constrains. This is a simple and powerful idea. + +Example: + +- service X receives request with ``grpc-timeout: 100m`` in metadata + (100m means 100 milliseconds) + + - service X immediately converts timeout into deadline: + + .. code-block:: python + + deadline = time.monotonic() + grpc_timeout + + - service X spent 20ms doing some work + + - now service X wants to make outgoing request to service Y, so it computes + how much time remains to perform this request: + + .. code-block:: python + + new_timeout = max(deadline - time.monotonic(), 0) # == 80ms + + - service X performs request to service Y with metadata ``grpc-timeout: 80m`` + + - service Y uses the same logic to convert timeout -> deadline -> timeout. + +With this feature it is possible to cancel whole call chain simultaneously, +even in case of network failures (broken connections). + grpclib ~~~~~~~ @@ -54,3 +107,5 @@ grpclib .. _multiplexing: http://httpwg.org/specs/rfc7540.html#StreamsLayer .. _flow control: http://httpwg.org/specs/rfc7540.html#FlowControl .. _HPACK: http://httpwg.org/specs/rfc7541.html +.. _gRPC format: https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md +.. _RST_STREAM: http://httpwg.org/specs/rfc7540.html#RST_STREAM