Store events and create deliveries in the delivery engine (closes #544)
check / check (push) Canceled after 0s

The receiver, resubmit and replay handlers now parse the request and
make one call. Engine.StoreEvent stores an event with a pending
delivery for each active target and the totals in one transaction,
then queues them; Engine.CreateReplay does the same for one replay
delivery. The handlers take *delivery.Engine, so the Notifier
interface and its bridge are gone, and the engine's notify is no
longer exported. Archives and CircuitBreakers stay because the handler
tests fake them. The tests that read a queued task moved to the
engine's tests; the handler tests use an engine that is never started.

Model: opus-5-5
This commit is contained in:
2026-10-15 22:07:23 +00:00
parent 8406c77949
commit 2113ba2771
21 changed files with 878 additions and 751 deletions
+15 -25
View File
@@ -171,37 +171,27 @@ func loadResubmitSource(
return src, true, nil
}
// queueResubmit stores the copy and fans it out to the webhook's
// active targets.
// queueResubmit has the delivery engine store the copy, with a delivery
// for each of the webhook's active targets as they stand now, exactly
// as it stores a received event.
func (h *Handlers) queueResubmit(
w http.ResponseWriter,
r *http.Request,
webhook database.Webhook,
src resubmitSource,
) {
// The receiver's own query, run now: an active target created
// after the original event arrived is included, and an
// inactive one is skipped rather than refused.
targets, err := h.loadActiveTargets(webhook.ID)
if err != nil {
h.serverError(w, r, "failed to query targets", err)
return
event := &database.Event{
WebhookID: webhook.ID,
EntrypointID: src.EntrypointID,
Method: src.Method,
RawQuery: src.RawQuery,
Headers: src.Headers,
ContentType: src.ContentType,
Body: string(src.Body),
ResubmittedFromID: &src.ID,
}
event, tasks, err := h.createAndFanOut(
eventSource{
WebhookID: webhook.ID,
EntrypointID: src.EntrypointID,
Method: src.Method,
RawQuery: src.RawQuery,
HeadersJSON: src.Headers,
ContentType: src.ContentType,
Body: src.Body,
ResubmittedFromID: &src.ID,
},
targets,
)
deliveries, err := h.engine.StoreEvent(event)
if err != nil {
h.serverError(w, r, "failed to store resubmitted event", err)
@@ -215,11 +205,11 @@ func (h *Handlers) queueResubmit(
"webhook_id", webhook.ID,
"event_id", event.ID,
"resubmitted_from_id", src.ID,
"target_count", len(tasks),
"target_count", deliveries,
)
code := resubmitQueued
if len(tasks) == 0 {
if deliveries == 0 {
code = resubmitNoTargets
}