[ 
https://issues.apache.org/jira/browse/KUDU-2065?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16082806#comment-16082806
 ] 

Michael Ho commented on KUDU-2065:
----------------------------------

cc'ing [~dhecht], [~henryr] and [~sailesh]

> Support cancellation for outbound client RPC
> --------------------------------------------
>
>                 Key: KUDU-2065
>                 URL: https://issues.apache.org/jira/browse/KUDU-2065
>             Project: Kudu
>          Issue Type: Improvement
>          Components: rpc
>            Reporter: Michael Ho
>            Priority: Minor
>
> Currently, there is no way to cancel an outbound client RPC call in Kudu. The 
> following is a proposal to do so. Please feel free to comment on it.
> A new interface {{void RpcController::Cancel()}} will be introduced. It 
> enqueues a reactor task which will eventually call {{void 
> OutboundCall::Cancel()}}. A new RpcFeature flag {{CANCELLABLE}} will be added 
> to indicate whether the server can handle in-flight RPC which is cancelled. 
> More details below. A client can specify whether such functionality
> is needed by setting a bool flag in {{RpcController}} passed to the proxy.
> Depending on the state of an OutboundCall, cancellation will happen as 
> follows:
> * READY
> ** it hasn't been scheduled yet. Set the cancellation flag in the 
> OutboundCall object. When it's eventually scheduled by 
> {{Connection::QueueOutboundCall()}}, it will check the cancellation flag 
> before assigining a {{call_id}}. If it's set, call 
> {{OutboundCall::SetCancelled()}} and return.
> * ON_OUTBOUND_QUEUE
> ** it's on the outbound transfer queue but transfer hasn't started yet.
> {{Connection::WriteHandler()}} will check the cancellation flag before 
> initiating a transfer. If it's set, the transfer will be popped from the 
> queue and deleted. Call {{OutboundCall::SetCancelled()}} and return.
> * SENDING
> ** some of the payload has already made its way to the other side. To make 
> sure the outbound call doesn't hold on to {{sidecars_}} till the end of the 
> transfer, the outbound call needs to clear {{sidecars_}} and sends the 
> remaining bytes as 0. The entry in CAR map will be removed and 
> {{OutboundCall::SetCancelled()}} will be invoked. Please see below on how the 
> server will handle this incomplete RPC message.
> * SENT
> ** The payload has been sent. Waiting for a response. Call 
> {{OutboundCall::SetCancelled()}}. Incoming response will be dropped on the 
> floor.
> * NEGOTIATION_TIMED_OUT
> * TIMED_OUT
> * CANCELLED
> * FINISHED_NEGOTIATION_ERROR
> * FINISHED_ERROR
> * FINISHED_SUCCESS
> ** No-op. Callback has been invoked already.
> {{OutboundCall::SetCancelled()}} will mark {{status_}} to {{Cancelled}}. Set 
> the state to {{CANCELLED}}. In addition, it will clear {{side_cars_}}, delete 
> {{header_buf_}} and invoke the callback.
> When an OutboundCall already in the {{SENDING}} state is cancelled, 
> {{sidecars_}} will be cleared. This provides guarantee to the RPC client that 
> the RPC subsystem doesn't have any reference left to payload pointed by 
> {{sidecars_}} so the RPC client can safely free them if it's passed in as a 
> SliceSideCar. It's freed immediately if it's passed in as FastStringSideCar. 
> An in-flight RPC will be cancelled by sending the remainder of the payload 
> (encoded in total message length) as 0. An optional bool field is added to 
> the request header. If it's set, it's expected that a single byte at the end 
> which is 1 if the payload has been cancelled when it was in-flight. 
> Potentially, we can do the same treatment for client RPC which times out 
> already.
> {noformat}
> +------------------------------------------------+
> | Total message length (4 bytes)                 |
> +------------------------------------------------+
> | RPC Header protobuf length (variable encoding) |
> +------------------------------------------------+
> | RPC Header protobuf                            |
> +------------------------------------------------+
> | Main message length (variable encoding)        |
> +------------------------------------------------+ --- 0
> | Main message protobuf                          |
> +------------------------------------------------+ --- sidecar_offsets(0)
> | Sidecar 0                                      |
> +------------------------------------------------+ --- sidecar_offsets(1)
> | Sidecar 1                                      |
> +------------------------------------------------+ --- sidecar_offsets(2)
> | Sidecar 2                                      |
> +------------------------------------------------+ --- ...
> | ...                                            |
> +------------------------------------------------+
> | cancelled                                      | -- true if RPC has been 
> cancelled mid-flight
> +------------------------------------------------+
> {noformat}



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to