fix: prevent RunDaemon from sending completed state before Close sends final logs

Split ReportState into a public method that skips when closed (used by
RunDaemon) and a private reportState that always sends (used by Close).
This prevents the server from deleting ephemeral runners before final
logs are uploaded. Add test reproducing the exact interleaving from #793.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
silverwind
2026-02-19 04:05:54 +01:00
parent 5e139031c6
commit 3e139b7f09
2 changed files with 91 additions and 1 deletions

View File

@@ -261,7 +261,7 @@ func (r *Reporter) Close(lastWords string) error {
if err := r.ReportLog(true); err != nil {
return err
}
return r.ReportState()
return r.reportState()
}, retry.Context(r.ctx))
}
@@ -300,7 +300,18 @@ func (r *Reporter) ReportLog(noMore bool) error {
return nil
}
// ReportState reports the current task state unless the reporter is closed.
func (r *Reporter) ReportState() error {
r.stateMu.RLock()
closed := r.closed
r.stateMu.RUnlock()
if closed {
return nil
}
return r.reportState()
}
func (r *Reporter) reportState() error {
r.clientM.Lock()
defer r.clientM.Unlock()