mirror of
https://gitea.com/gitea/act_runner.git
synced 2026-06-13 13:24:23 +02:00
feat: complete runner-side cancellation handling (#1016)
Completes the runner side of the cancellation flow, superseding #825. Two parts: ### 1. Report cancellations correctly (`fix`) When `Reporter.Close` ran with the state still `UNSPECIFIED` and the reporter's context had been cancelled, the synthesised final state attributed the job to `RESULT_FAILURE` with an "Early termination" log row — misreporting a cancellation as a generic failure. `Close` now detects the cancelled context and finalizes the task as `RESULT_CANCELLED`. ### 2. Advertise the `cancelling` capability (`feat`) [actions-proto-go v0.6.0](https://gitea.com/gitea/actions-proto-go) adds a `capabilities` field to `RegisterRequest`/`DeclareRequest`, so the runner can now tell the server it understands the transitional cancelling state: - Bumps `gitea.dev/actions-proto-go` to `v0.6.0`. - Adds a single `RunnerCapabilities()` source of truth exposing `CapabilityCancelling`. - Sends `Capabilities` on both register and declare. With this the server records `HasCancellingSupport` and can rely on the runner running post-step cleanup before a task is finalized as `RESULT_CANCELLED`. ## Compatibility Wire-compatible against older servers: the new field uses a previously unused field number (8 on `RegisterRequest`, 3 on `DeclareRequest`) and the client uses the binary protobuf codec, so a server predating the field silently ignores it — registration and declaration succeed and the feature simply stays off. It activates only once both runner and server are on v0.6.0. ## Server side The matching Gitea change (read `GetCapabilities()`, persist `HasCancellingSupport`) is a separate PR against `gitea/gitea`. Supersedes #825. Reviewed-on: https://gitea.com/gitea/runner/pulls/1016 Reviewed-by: Zettat123 <39446+zettat123@noreply.gitea.com> Reviewed-by: wxiaoguang <29147+wxiaoguang@noreply.gitea.com>
This commit is contained in:
@@ -391,15 +391,28 @@ func (r *Reporter) Close(lastWords string) error {
|
||||
r.stateMu.Lock()
|
||||
r.closed = true
|
||||
if r.state.Result == runnerv1.Result_RESULT_UNSPECIFIED {
|
||||
// When r.ctx has been cancelled (server returned RESULT_CANCELLED via
|
||||
// rpcCtx/ReportState, see line 590) the job is being torn down on the
|
||||
// cancellation path: surface that explicitly instead of attributing it
|
||||
// to a generic failure.
|
||||
cancelled := errors.Is(r.ctx.Err(), context.Canceled)
|
||||
if lastWords == "" {
|
||||
lastWords = "Early termination"
|
||||
if cancelled {
|
||||
lastWords = "Cancelled"
|
||||
} else {
|
||||
lastWords = "Early termination"
|
||||
}
|
||||
}
|
||||
for _, v := range r.state.Steps {
|
||||
if v.Result == runnerv1.Result_RESULT_UNSPECIFIED {
|
||||
v.Result = runnerv1.Result_RESULT_CANCELLED
|
||||
}
|
||||
}
|
||||
r.state.Result = runnerv1.Result_RESULT_FAILURE
|
||||
if cancelled {
|
||||
r.state.Result = runnerv1.Result_RESULT_CANCELLED
|
||||
} else {
|
||||
r.state.Result = runnerv1.Result_RESULT_FAILURE
|
||||
}
|
||||
r.logRows = append(r.logRows, &runnerv1.LogRow{
|
||||
Time: timestamppb.Now(),
|
||||
Content: lastWords,
|
||||
|
||||
Reference in New Issue
Block a user