Backport #37631 by @silverwind `UpdateLog` short-circuits on `len(Rows)==0` before honoring `NoMore`, so a final empty `UpdateLog{NoMore:true}` never runs `TransferLogs`. The task's `dbfs_data` rows are then never moved to log storage and never deleted. The bug has been latent since the original Actions implementation, `act_runner` versions after [runner#819](https://gitea.com/gitea/runner/pulls/819) trip it deterministically. Fix: let `NoMore=true` with no new rows fall through to `TransferLogs`. Bail when the runner has outrun the server (`Index > ack`) even with `NoMore`, since archiving a log with a gap is worse than retrying. Always call `WriteLogs` so `offset==0` bootstraps an empty DBFS file in the no-output case (otherwise `TransferLogs` would fail at `dbfs.Open`). Fixes: https://github.com/go-gitea/gitea/issues/37623 Ref: [runner#952](https://gitea.com/gitea/runner/pulls/952) Ref: [runner#950](https://gitea.com/gitea/runner/pulls/950) --- This PR was written with the help of Claude Opus 4.7 Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
This commit is contained in:
@@ -264,7 +264,16 @@ func (s *Service) UpdateLog(
|
||||
}
|
||||
ack := task.LogLength
|
||||
|
||||
if len(req.Msg.Rows) == 0 || req.Msg.Index > ack || int64(len(req.Msg.Rows))+req.Msg.Index <= ack {
|
||||
// Trim rows the runner already had acked.
|
||||
var rows []*runnerv1.LogRow
|
||||
if req.Msg.Index <= ack && int64(len(req.Msg.Rows))+req.Msg.Index > ack {
|
||||
rows = req.Msg.Rows[ack-req.Msg.Index:]
|
||||
}
|
||||
|
||||
// Bail unless we have new rows or a NoMore to finalize. Even with
|
||||
// NoMore, bail when the runner has outrun the server — archiving a
|
||||
// log with a gap is worse than asking it to retry.
|
||||
if len(rows) == 0 && (!req.Msg.NoMore || req.Msg.Index > ack) {
|
||||
res.Msg.AckIndex = ack
|
||||
return res, nil
|
||||
}
|
||||
@@ -273,7 +282,9 @@ func (s *Service) UpdateLog(
|
||||
return nil, status.Errorf(codes.AlreadyExists, "log file has been archived")
|
||||
}
|
||||
|
||||
rows := req.Msg.Rows[ack-req.Msg.Index:]
|
||||
// WriteLogs is called even with no rows: with offset==0 it bootstraps
|
||||
// an empty DBFS file so TransferLogs below has something to read when
|
||||
// the runner finalizes a task that produced no log output.
|
||||
ns, err := actions.WriteLogs(ctx, task.LogFilename, task.LogSize, rows)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "unable to append logs to dbfs file: %v", err)
|
||||
|
||||
Reference in New Issue
Block a user