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

Todd Lipcon commented on KUDU-2065:
-----------------------------------

Good proposal, and thanks for the nice thorough write-up enumerating the 
possible states, etc.

Regarding the point about cancellation during SENT state, I think we can 
potentially split this work into two related but not quite coupled tasks:

1) add cancellation as described here, but not taking into account the SENT 
state

2) properly handle sidecar destruction when a client times out while sending -- 
this is to solve the pre-existing lifecycle issue with request sidecars 
(KUDU-2011). The solution of the one-byte "trailer" on request is one option 
here. We could also consider a more complex option in which sidecars are 
chunked/framed like 'CONTINUE <32kb data> CONTINUE <32kb data> FINISHED' vs 
'CONTINUE <32kb data> ABORT'. There is some potential expense at the server 
side here in that the number of read() syscalls is increased, so we may need to 
fiddle with that 32kb size.

3) after both of the above are done, we can make the cancellation basically 
equivalent to an "early timeout"

4) not mentioned in the proposal above, we may at some point want to add a 
protocol for the client sending early cancellation of a request which is 
already in the SENT state. It might not be as useful in Impala but we could 
certainly use it in Kudu. It seems like a natural extension of this work, 
though, so no need to do it at the same time.

> 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