Documentation
¶
Index ¶
- func CancelByKey(tx *sql.Tx, cancelKey string) error
- func CancelForProject(tx *sql.Tx, projectId uuid.UUID) error
- func DrainOnce(ctx context.Context, now time.Time)
- func Enqueue(tx *sql.Tx, d Delivery) (int, error)
- func PageCancelKey(pageId int) string
- func RegisterSender(fn SendFunc)
- func RegisterTerminalHook(fn TerminalHook)
- func StartDrain(ctx context.Context)
- func VerificationCancelKey(methodId int) string
- func Wake()
- type Delivery
- type HealthStats
- type SendFunc
- type TerminalHook
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CancelByKey ¶
CancelByKey flips every pending/sending row under the key to cancelled and mirrors their linked page_notifications rows. Runs in the caller's transaction. An in-flight send may still deliver once (at-least-once), but the row's final state stays cancelled: MarkSent/MarkFailedWithBackoff are guarded on status = 'sending'.
func CancelForProject ¶
CancelForProject cancels everything still queued for a project (which has no foreign key from notification_outbox), in the caller's transaction.
func DrainOnce ¶
DrainOnce runs a single drain tick: reclaim stale sending rows, claim due rows, deliver them, finalize. Exported so tests (and tooling) can drive the outbox deterministically.
func Enqueue ¶
Enqueue inserts a pending outbox row in the caller's transaction. The commit of that transaction is the durable "someone will be notified" promise. Callers should Wake() after their transaction commits.
func PageCancelKey ¶
func RegisterSender ¶
func RegisterSender(fn SendFunc)
func RegisterTerminalHook ¶
func RegisterTerminalHook(fn TerminalHook)
func StartDrain ¶
StartDrain runs the outbox drain loop: claim due rows in a transaction (marking them sending), deliver after commit, finalize each row in its own small transaction. All state lives in notification_outbox, so a crash at any point is recovered: unclaimed rows stay due, stale sending rows are reclaimed, and the guarded status transitions make cancellation win races.
func VerificationCancelKey ¶
VerificationCancelKey scopes a contact method's verification sends so a new code supersedes the one before it.
Types ¶
type Delivery ¶
type Delivery struct {
Kind string
AdapterType string
AdapterConfig json.RawMessage
Message models.NotificationMessage
NotBefore *time.Time
CancelKey string
PageNotificationId *int
RuleId *int
ProjectId *uuid.UUID
ChannelName string
}
Delivery is one intended notification send. Enqueue persists it; the drain worker delivers it with retries. AdapterConfig is a snapshot: it is never re-derived at send time, so later channel/contact-method edits do not affect rows already queued.
type HealthStats ¶
type HealthStats struct {
Pending int `json:"pending"`
Sending int `json:"sending"`
OldestPendingAgeSec int64 `json:"oldestPendingAgeSec"`
FailedRows int `json:"failedRows"`
SentTotal uint64 `json:"sentTotal"`
TerminalFailuresTotal uint64 `json:"terminalFailuresTotal"`
}
func HealthSnapshot ¶
func HealthSnapshot() (*HealthStats, error)
HealthSnapshot powers /api/health/deep. OldestPendingAgeSec measures due-age (from next_attempt_at), so a scheduled future delivery does not look stuck.
type SendFunc ¶
type SendFunc func(ctx context.Context, adapterType string, adapterConfig json.RawMessage, msg models.NotificationMessage) error
SendFunc performs one delivery attempt. Registered from cmd/run.go with the notifications-package implementation; the indirection exists because this package cannot import notifications (notifications imports it to enqueue).
type TerminalHook ¶
type TerminalHook func(row *models.OutboxDelivery, status string, errorMsg string)
TerminalHook observes terminal outcomes (models.OutboxSent or models.OutboxFailed) for audit bookkeeping. Called outside any transaction; must not block.