check / check (push) Successful in 3m4s
The per-webhook event databases had no secondary indexes, so startup recovery, the retry and pending sweeps, the queue-depth sampler, the event log and retention each read whole tables. Indexes declared in the GORM model tags now serve them, and AutoMigrate adds them to new and existing databases alike. Each index also covers deleted_at: GORM adds deleted_at IS NULL to these queries, and SQLite, with no table statistics, otherwise prefers the existing deleted_at index. A test checks SQLite's plan for each statement as GORM builds it. Rule suppressed: lll on the three event-tier model structs, whose struct tags cannot wrap. The resubmitted_from_id scan is left to #325. Model: opus-4-8 (implementation); opus-5-5 (rework)
53 lines
1.8 KiB
Go
53 lines
1.8 KiB
Go
package database
|
|
|
|
import "gorm.io/gorm"
|
|
|
|
// DeliveryStatus represents the status of a delivery
|
|
type DeliveryStatus string
|
|
|
|
// Delivery status values.
|
|
const (
|
|
DeliveryStatusPending DeliveryStatus = "pending"
|
|
DeliveryStatusDelivered DeliveryStatus = "delivered"
|
|
DeliveryStatusFailed DeliveryStatus = "failed"
|
|
DeliveryStatusRetrying DeliveryStatus = "retrying"
|
|
)
|
|
|
|
// Terminal reports whether a delivery in this status has finished, so
|
|
// the delivery engine will make no further attempt of its own.
|
|
//
|
|
// It is what decides which deliveries the event log offers to replay:
|
|
// a pending or retrying delivery is still the engine's, and replaying
|
|
// one would race it.
|
|
func (s DeliveryStatus) Terminal() bool {
|
|
switch s {
|
|
case DeliveryStatusDelivered, DeliveryStatusFailed:
|
|
return true
|
|
case DeliveryStatusPending, DeliveryStatusRetrying:
|
|
return false
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
// Delivery represents a delivery attempt for an event to a target
|
|
//
|
|
//nolint:lll // a struct tag cannot wrap
|
|
type Delivery struct {
|
|
BaseModel
|
|
|
|
EventID string `gorm:"type:uuid;not null;index:idx_deliveries_event_id,priority:1" json:"eventId"`
|
|
TargetID string `gorm:"type:uuid;not null" json:"targetId"`
|
|
Status DeliveryStatus `gorm:"not null;default:'pending';index:idx_deliveries_status,priority:1" json:"status"`
|
|
|
|
// DeletedAt repeats the BaseModel field only to be the second column
|
|
// of the event_id and status indexes, for the reason DeliveryResult
|
|
// gives.
|
|
DeletedAt gorm.DeletedAt `gorm:"index:idx_deliveries_event_id,priority:2;index:idx_deliveries_status,priority:2" json:"deletedAt,omitzero"`
|
|
|
|
// Relations
|
|
Event Event `json:"event,omitzero"`
|
|
Target Target `json:"target,omitzero"`
|
|
DeliveryResults []DeliveryResult `json:"deliveryResults,omitempty"`
|
|
}
|