|  | :linkattrs: | 
|  | = Request Cancellation and Deadlines | 
|  |  | 
|  | [[motivation]] | 
|  | == Motivation | 
|  |  | 
|  | Protect the Gerrit service by aborting requests that were cancelled or for which | 
|  | the deadline has exceeded. If these requests are not aborted, it can happen that | 
|  | too many of these requests are accumulated so that the server runs out of | 
|  | resources (e.g. threads). | 
|  |  | 
|  | [[request-cancellation]] | 
|  | == Request Cancellation | 
|  |  | 
|  | If a user cancels a request by disconnecting, ideally Gerrit should detect this | 
|  | and abort the request execution to avoid doing unnecessary work. If nobody is | 
|  | waiting for the response, Gerrit shouldn't spend resources to compute it. | 
|  |  | 
|  | Detecting cancelled requests is not easily possible with all protocols that a | 
|  | client may use. At the moment Gerrit only detects request cancellations for git | 
|  | pushes, but not for other request types (in particular cancelled requests are | 
|  | not detected for REST calls over HTTP, SSH commands and git clone/fetch). | 
|  |  | 
|  | [[server-side-deadlines]] | 
|  | == Server-side deadlines | 
|  |  | 
|  | To limit the maximal execution time for requests, administrators can | 
|  | link:config-gerrit.html#deadline.id[configure server-side deadlines]. If a | 
|  | server-side deadline is exceeded by a matching request, the request is | 
|  | automatically aborted. In this case the client gets a proper error message | 
|  | informing the user about the exceeded deadline. | 
|  |  | 
|  | Clients may override server-side deadlines by setting a | 
|  | link:#client-provided-deadlines[deadline] on the request. This means, if a | 
|  | request fails due to an exceeded server-side deadline, the client may repeat the | 
|  | request with a higher deadline or no deadline (deadline = 0) to get unblocked. | 
|  |  | 
|  | Server-side deadlines are meant to protect the Gerrit service against resource | 
|  | exhaustion due to performence issues with a particular request. E.g. imagine a | 
|  | situation where requests for a certain REST endpoint are very slow. If more and | 
|  | more of such requests get stuck and are not being aborted, the Gerrit service | 
|  | may run out of threads, causing an outage for the entire Gerrit service. | 
|  | Server-side deadlines may prevent this because the slow requests get aborted | 
|  | after the deadline is exceeded, and hence the server resources are freed up. | 
|  |  | 
|  | In some cases server-side deadlines may also lead to a better user experience, | 
|  | as it's better to tell the user that there is a performance issue, that prevents | 
|  | the execution of the request, than letting them wait indefinitely. | 
|  |  | 
|  | Finally server-side deadlines can help ops engineers to detect performance | 
|  | issues more reliably and more quicky. For this alerts may be setup that are | 
|  | based on the link:metrics.html#cancellations[cancellation metrics]. | 
|  |  | 
|  | [[receive-timeout]] | 
|  | === Receive Timeout | 
|  |  | 
|  | For git pushes it is possible to configure a | 
|  | link:config-gerrit.html#receive.timeout[hard timeout]. In contrast to | 
|  | server-side deadlines, this timeout is not overridable by | 
|  | link:#client-provided-deadlines[client-provided deadlines]. | 
|  |  | 
|  | [[client-provided-deadlines]] | 
|  | == Client-provided deadlines | 
|  |  | 
|  | Clients can set a deadline on requests to limit the maximal execution time that | 
|  | they are willing to wait for a response. If the request doesn't finish within | 
|  | this deadline the request is aborted and the client receives an error, with a | 
|  | message telling them that the deadline has been exceeded. | 
|  |  | 
|  | How to set a deadline on a request depends on the request type: | 
|  |  | 
|  | [options="header",cols="1,6"] | 
|  | |======================= | 
|  | |Request Type   |How to set a deadline? | 
|  | |REST over HTTP |Set the link:rest-api.html#deadline[X-Gerrit-Deadline header]. | 
|  | |SSH command    |Set the link:cmd-index.html#deadline[deadline option]. | 
|  | |git push       |Set the link:user-upload.html#deadline[deadline push option]. | 
|  | |git clone/fetch|Not supported. | 
|  | |======================= | 
|  |  | 
|  | [[override-server-side-deadline]] | 
|  | === Override server-side deadline | 
|  |  | 
|  | By setting a deadline on a request it is possible to override any | 
|  | link:#server-side-deadlines[server-side deadline], e.g. in order to increase it. | 
|  | Setting the deadline to `0` disables any server-side deadline. This allows | 
|  | clients to get unblocked if a request has previously failed due to an exceeded | 
|  | deadline. | 
|  |  | 
|  | [NOTE] | 
|  | It is stronly discouraged for clients to permanently override | 
|  | link:#server-side-deadlines[server-side deadlines] with a higher deadline or to | 
|  | permanently disable them by always setting the deadline to `0`. If this becomes | 
|  | necessary the caller should get in touch with the Gerrit administrators to | 
|  | increase the server-side deadlines or resolve the performance issue in another | 
|  | way. | 
|  |  | 
|  | [NOTE] | 
|  | It's not possible for clients to override the link:#receive-timeout[receive | 
|  | timeout] that is enforced on git push. | 
|  |  | 
|  | [[faqs]] | 
|  | == FAQs | 
|  |  | 
|  | [[deadline-exceeded-what-to-do]] | 
|  | === My request failed due to an execeeded deadline, what can I do? | 
|  |  | 
|  | To get unblocked, you may repeat the request with deadlines disabled. To do this | 
|  | set the deadline to `0` on the request as explained | 
|  | link:#override-server-side-deadline[above]. | 
|  |  | 
|  | If doing this becomes required frequently, please get in touch with the Gerrit | 
|  | administrators in order to investigate the performance issue and increase the | 
|  | server-side deadline if necessary. | 
|  |  | 
|  | [NOTE] | 
|  | Setting deadlines for requests that are done from the Gerrit web UI is not | 
|  | possible. If exceeded deadlines occur frequently here, please get in touch with | 
|  | the Gerrit administrators in order to investigate the performance issue. | 
|  |  | 
|  | [[push-fails-due-to-exceeded-deadline-but-cannot-be-overridden]] | 
|  | === My git push fails due to an exceeded deadline and I cannot override the deadline, what can I do? | 
|  |  | 
|  | As explained link:#receive-timeout[above] a configured receive timeout cannot be | 
|  | overridden by clients. If pushes fail due to this timeout, get in touch with the | 
|  | Gerrit administrators in order to investigate the performance issue and increase | 
|  | the receive timeout if necessary. | 
|  |  | 
|  | [[when-are-requests-aborted]] | 
|  | === How quickly does a request get aborted when it is cancelled or a deadline is exceeded? | 
|  |  | 
|  | In order to know if a request should be aborted, Gerrit needs to explicitly | 
|  | check whether the request is cancelled or whether a deadline is exceeded. | 
|  | Gerrit does this check at the beginning and end of all performance critical | 
|  | steps and sub-steps. This means, the request is only aborted the next time such | 
|  | a step starts or finishes, which can also be never (e.g. if the request is stuck | 
|  | inside of a step). | 
|  |  | 
|  | [NOTE] | 
|  | Technically the check whether a request should be aborted is done whenever the | 
|  | execution time of an operation or sub-step is captured, either by a timer | 
|  | metric or a `TraceTimer` ('TraceTimer` is the class that logs the execution time | 
|  | when the request is being link:user-request-tracing.html[traced]). | 
|  |  | 
|  | [[how-are-requests-aborted]] | 
|  | === How does Gerrit abort requests? | 
|  |  | 
|  | The exact response that is returned to the client depends on the request type | 
|  | and the cancellation reason: | 
|  |  | 
|  | [options="header",cols="1,3,3"] | 
|  | |======================= | 
|  | |Request Type   |Cancellation Reason|Response | 
|  | |REST over HTTP |Client Disconnected|The response is '499 Client Closed Request'. | 
|  | |               |Server-side deadline exceeded|The response is '408 Server Deadline Exceeded'. | 
|  | |               |Client-provided deadline exceeded|The response is '408 Client Provided Deadline Exceeded'. | 
|  | |SSH command    |Client Disconnected|The error message is 'Client Closed Request'. | 
|  | |               |Server-side deadline exceeded|The error message is 'Server Deadline Exceeded'. | 
|  | |               |Client-provided deadline exceeded|The error message is 'Client Provided Deadline Exceeded'. | 
|  | |git push       |Client Disconnected|The error status is 'Client Closed Request'. | 
|  | |               |Server-side deadline exceeded|The error status is 'Server Deadline Exceeded'. | 
|  | |               |Client-provided deadline exceeded|The error status is 'Client Provided Deadline Exceeded'. | 
|  | |git clone/fetch|Not supported. | 
|  | |======================= | 
|  |  | 
|  | This means clients always get a proper error message telling the user why the | 
|  | request has been aborted. | 
|  |  | 
|  | Errors due to aborted requests are usually not counted as internal server errors, | 
|  | but the link:metrics.html#cancellations[cancellation metrics] may be used to | 
|  | setup alerting for performance issues. | 
|  |  | 
|  | [NOTE] | 
|  | During a request, cancellations can occur at any time. This means for non-atomic | 
|  | operations, it can happen that the operation is cancelled after some steps have | 
|  | already been successfully performed and before all steps have been executed, | 
|  | potentially leaving behind an inconsistent state (same as when a request fails | 
|  | due to an error). However for important steps, such a NoteDb updates that span | 
|  | multiple repositories, Gerrit ensures that they are not torn by cancellations. | 
|  |  | 
|  | GERRIT | 
|  | ------ | 
|  | Part of link:index.html[Gerrit Code Review] | 
|  |  | 
|  | SEARCHBOX | 
|  | --------- |