Skip to content

feat(agent): completion webhook + always-on heartbeat tag (#497) - #498

Merged
scttfrdmn merged 1 commit into
mainfrom
feat/497-completion-webhook-heartbeat
Aug 11, 2026
Merged

feat(agent): completion webhook + always-on heartbeat tag (#497)#498
scttfrdmn merged 1 commit into
mainfrom
feat/497-completion-webhook-heartbeat

Conversation

@scttfrdmn

Copy link
Copy Markdown
Contributor

Summary

Closes spawn#497's two independent asks:

  1. --completion-webhook-url — spored now POSTs a fire-once, best-effort notice when the completion sentinel fires, mirroring the existing --spot-webhook-url (Optional fire-and-forget spot-interruption webhook (the named agent.go:1066 enhancement) #228) pattern exactly. Fired from checkCompletion before the grace-period sleep/action, so a caller learns of completion as early as spored itself does. Shares --webhook-correlation/--webhook-timeout with the spot webhook. This lets a consumer (e.g. calque) register its own webhook/queue target instead of reinventing an S3-artifact-polling loop unaware of spored's own on-instance sentinel.

  2. spawn:last-heartbeat EC2 tag — stamped with the current time on every monitor tick (throttled to once/minute, matching the production monitor interval), unconditionally, no opt-in flag needed. Gives any poller (calque, spawn task run --wait, or a third party) a way to tell "still alive and ticking" from "hung" or "gone" — closing the gap where a caller had no choice but to pre-commit to one wall-clock number and treat exceeding it as failure.

Both changes are additive: no existing behavior, flag, or tag changes shape when unconfigured (both new capabilities are strictly off by default except the heartbeat, which is unconditional but harmless to callers who never read it).

Real-world motivation (from the issue): a real vLLM run under calque was still legitimately executing at 40 minutes with no way to distinguish "almost done" from "stuck" other than the caller's own guessed deadline.

Test plan

  • go build ./...
  • go vet ./...
  • make check (fmt/vet/lint/short tests) — green
  • New unit tests: completion-webhook payload/echo, disabled-when-no-URL, best-effort-drop-on-5xx, end-to-end wiring via checkCompletion, heartbeat-tag throttle guard, buildTags opt-in tag round-trip
  • All pre-existing tests pass unchanged (no behavior change for callers not using the new flag)
  • make gen-docsdocs-gen/launch.md regenerated and committed

Closes the caller-facing gap where waiting for a launched instance's
workload meant polling an artifact against a pre-guessed wall-clock
deadline (the flaw behind a real calque incident). --completion-webhook-url
mirrors the existing --spot-webhook-url (#228) fire-once POST pattern,
fired from checkCompletion before the grace-period sleep. Independently,
spawn:last-heartbeat is now stamped on every monitor tick (throttled to
1/min) unconditionally, giving a poller a liveness signal that needs no
guessed timeout at all.
@codecov

codecov Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 61.40351% with 22 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
pkg/agent/agent.go 61.90% 15 Missing and 1 partial ⚠️
cmd/launch_config.go 0.00% 3 Missing and 1 partial ⚠️
pkg/provider/ec2.go 0.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@scttfrdmn
scttfrdmn merged commit 6ca744b into main Aug 11, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant