Commit 8316a06
Eric Bower
·
2026-05-08 11:35:58 -0400 EDT
parent 4eaacc1
fix: published.json
1 files changed,
+11,
-6
M
main.go
M
main.go
+11,
-6
| ... | ... | @@ -1047,6 +1047,7 @@ func monitorTick(cfg *Cfg, log *slog.Logger, output io.Writer, jobStates map[str | |
| 1047 | 1047 | if allCompleted(group) { | |
| 1048 | 1048 | // Check sentinel — publish terminal status exactly once | |
| 1049 | 1049 | sentinel := filepath.Join(cfg.ArtifactDir, name, jobID, "published.json") | |
| 1050 | + | log.Debug("checking completion", "all_completed", true, "sentinel", sentinel) | |
| 1050 | 1051 | if _, err := os.Stat(sentinel); err == nil { | |
| 1051 | 1052 | log.Debug("terminal status already published, skipping", "sentinel", sentinel) | |
| 1052 | 1053 | continue |
| ... | ... | @@ -1075,11 +1076,10 @@ func monitorTick(cfg *Cfg, log *slog.Logger, output io.Writer, jobStates map[str | |
| 1075 | 1076 | log.Error("publish final status", "err", err) | |
| 1076 | 1077 | } | |
| 1077 | 1078 | } | |
| 1078 | - | // Sync artifacts before writing sentinel — syncArtifacts skips jobs with published.json | |
| 1079 | - | if err := syncJobArtifacts(cfg, name, jobID, log); err != nil { | |
| 1080 | - | log.Error("sync artifacts", "err", err) | |
| 1081 | - | } | |
| 1082 | - | // Write sentinel so we don't re-publish on subsequent ticks | |
| 1079 | + | // Write published.json, then sync to include it in the rsync. | |
| 1080 | + | // syncArtifacts at end-of-tick will skip this job (has published.json), | |
| 1081 | + | // so this is the only sync for completed jobs. In-progress jobs are | |
| 1082 | + | // synced every tick by syncArtifacts (no published.json yet). | |
| 1083 | 1083 | published := map[string]interface{}{ | |
| 1084 | 1084 | "status": status, | |
| 1085 | 1085 | "exit_code": exitCode, |
| ... | ... | @@ -1087,9 +1087,13 @@ func monitorTick(cfg *Cfg, log *slog.Logger, output io.Writer, jobStates map[str | |
| 1087 | 1087 | "finished_at": time.Now().UTC().Format(time.RFC3339), | |
| 1088 | 1088 | } | |
| 1089 | 1089 | publishedJSON, _ := json.Marshal(published) | |
| 1090 | + | log.Info("writing sentinel", "path", sentinel) | |
| 1090 | 1091 | if err := os.WriteFile(sentinel, publishedJSON, 0644); err != nil { | |
| 1091 | 1092 | log.Error("write published sentinel", "err", err) | |
| 1092 | 1093 | } | |
| 1094 | + | if err := syncJobArtifacts(cfg, name, jobID, log); err != nil { | |
| 1095 | + | log.Error("sync artifacts", "err", err) | |
| 1096 | + | } | |
| 1093 | 1097 | } else { | |
| 1094 | 1098 | log.Debug("job still running", "sessions", len(group)) | |
| 1095 | 1099 | // Publish running status only when --include-running is set |
| ... | ... | @@ -1530,7 +1534,8 @@ func syncArtifacts(cfg *Cfg, log *slog.Logger) error { | |
| 1530 | 1534 | jobDir := filepath.Join(cfg.ArtifactDir, entry.Name(), repoEntry.Name()) | |
| 1531 | 1535 | publishedPath := filepath.Join(jobDir, "published.json") | |
| 1532 | 1536 | ||
| 1533 | - | // Skip if already published (job is complete) | |
| 1537 | + | // Skip if job is complete (published.json exists) | |
| 1538 | + | // In-progress jobs are synced every tick; completed jobs are skipped. | |
| 1534 | 1539 | if _, err := os.Stat(publishedPath); err == nil { | |
| 1535 | 1540 | continue | |
| 1536 | 1541 | } |