check / check (push) Waiting to run
Replaces #559, which conflicted. Model: opus-5-5
88 lines
2.0 KiB
Go
88 lines
2.0 KiB
Go
package delivery
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
"sneak.berlin/go/webhooker/internal/database"
|
|
)
|
|
|
|
// databaseTarget is a no-retry target that archives the full
|
|
// inbound event into the target's own archive SQLite file, separate
|
|
// from the per-webhook event database. The event is already
|
|
// persisted in the per-webhook event DB by the time delivery runs;
|
|
// the database target additionally writes a durable long-term copy
|
|
// through the engine's archive.Writers, and then records a single
|
|
// attempt whose outcome reflects whether the archive write
|
|
// succeeded. Package archive holds everything about the files
|
|
// themselves.
|
|
type databaseTarget struct {
|
|
eng *Engine
|
|
}
|
|
|
|
// Deliver implements Target. It archives the event, then
|
|
// records one successful attempt and marks the delivery
|
|
// delivered. An archiving error fails the delivery: the
|
|
// attempt is recorded as failed with the error and the
|
|
// delivery is marked failed, so a target that could not do
|
|
// its one job (archiving) never reports success. The target
|
|
// does not retry; the event remains durably stored in the
|
|
// per-webhook event database.
|
|
func (t *databaseTarget) Deliver(
|
|
_ context.Context,
|
|
webhookDB *gorm.DB,
|
|
d *database.Delivery,
|
|
_ *Task,
|
|
_ Scheduler,
|
|
) {
|
|
start := time.Now()
|
|
|
|
err := t.eng.archives.Write(d)
|
|
|
|
elapsed := time.Since(start)
|
|
|
|
t.eng.observeAttempt(d.Target.Type, elapsed)
|
|
|
|
if err != nil {
|
|
t.eng.log.Error(
|
|
"failed to archive event to database target",
|
|
"delivery_id", d.ID,
|
|
"event_id", d.EventID,
|
|
"error", err,
|
|
)
|
|
|
|
recErr := t.eng.recordResult(
|
|
webhookDB, d, 1, false, 0, "",
|
|
err.Error(), elapsed.Milliseconds(),
|
|
)
|
|
if recErr != nil {
|
|
t.eng.bookkeepingFailed(d, recErr)
|
|
|
|
return
|
|
}
|
|
|
|
t.eng.settleStatus(
|
|
webhookDB, d, d.Target.Type,
|
|
database.DeliveryStatusFailed,
|
|
)
|
|
|
|
return
|
|
}
|
|
|
|
recErr := t.eng.recordResult(
|
|
webhookDB, d, 1, true, 0, "", "",
|
|
elapsed.Milliseconds(),
|
|
)
|
|
if recErr != nil {
|
|
t.eng.bookkeepingFailed(d, recErr)
|
|
|
|
return
|
|
}
|
|
|
|
t.eng.settleStatus(
|
|
webhookDB, d, d.Target.Type,
|
|
database.DeliveryStatusDelivered,
|
|
)
|
|
}
|