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, ) }