eventhook

package
v0.9.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 6, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

Package eventhook delivers platform events to operator-configured HTTPS endpoints: signed, queued, retried with backoff, dead-lettered after the last attempt, and recorded in a delivery log that supports replay.

Index

Constants

View Source
const (
	EnvMaxAttempts = "APP_EVENT_WEBHOOK_MAX_ATTEMPTS"
	EnvBackoffBase = "APP_EVENT_WEBHOOK_BACKOFF_BASE"
	EnvBackoffMax  = "APP_EVENT_WEBHOOK_BACKOFF_MAX"
	EnvSendTimeout = "APP_EVENT_WEBHOOK_TIMEOUT"
	EnvRetention   = "APP_EVENT_WEBHOOK_RETENTION"
	EnvQueueSize   = "APP_EVENT_WEBHOOK_QUEUE_SIZE"
)

Environment variables that tune delivery.

Variables

View Source
var ErrInvalid = errors.New("invalid event webhook")

ErrInvalid wraps every validation failure so callers can answer 400.

View Source
var ErrSecretsUnavailable = errors.New("eventhook: secret storage is not configured")

ErrSecretsUnavailable is returned when no master key is configured.

Functions

func Backoff

func Backoff(cfg Config, attempts int) time.Duration

Backoff is the wait before attempt number attempts+1: exponential from BackoffBase, capped at BackoffMax.

func EventTypes

func EventTypes() []string

EventTypes lists the event types the platform emits today, sorted.

func Matches

func Matches(subscribed []string, eventType string) bool

Matches reports whether a subscription list selects an event type. An empty list selects everything; "family.*" selects a name prefix.

func TypeForRequest

func TypeForRequest(method, path, action string) string

TypeForRequest names the event for one audited mutation: the audit action when the handler set one, else "<resource>.<verb>" from the request path.

Types

type Config

type Config struct {
	MaxAttempts int
	BackoffBase time.Duration
	BackoffMax  time.Duration
	SendTimeout time.Duration
	Retention   time.Duration
	Tick        time.Duration
	BatchSize   int
	QueueSize   int
}

Config bounds queueing, retries and retention.

func ConfigFromEnv

func ConfigFromEnv(lookup func(string) (string, bool)) Config

ConfigFromEnv applies env overrides on top of DefaultConfig. Unparseable or non-positive values are ignored.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig is the config used when no env override is set.

type Counts

type Counts struct {
	Pending, Delivered, Dead int
	LastStatus               int
	LastAt                   time.Time
}

Counts summarises delivery state for the list view.

type Deps

type Deps struct {
	Store   Store
	Secrets Secrets
	Config  Config
	// RetentionDays, when set, supplies the live delivery retention in days (0 keeps everything) instead of Config.Retention.
	RetentionDays func(ctx context.Context) int
	Brand         string
	Logger        *slog.Logger
	HTTPClient    *http.Client
	Now           func() time.Time
}

Deps wires a Service.

type Event

type Event struct {
	Type string
	Data map[string]any
}

Event is one thing that happened, as handed to Emit.

type Input

type Input struct {
	Name    string
	URL     string
	Enabled bool
	Events  []string
}

Input is the writable part of a webhook.

type Outcome

type Outcome struct {
	State     string
	NextAfter time.Duration
}

Outcome is the decision after one send attempt.

func Decide

func Decide(cfg Config, attempts, status int, sendErr error) Outcome

Decide maps an attempt result to the delivery's next state. attempts is the count including the attempt just made; permanent failures (a 4xx that a retry cannot fix) go straight to the dead letter state.

type Patch

type Patch struct {
	Name    *string
	URL     *string
	Enabled *bool
	Events  *[]string
}

Patch holds the optional changes of an update.

type Secrets

type Secrets interface {
	SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
	Resolve(ctx context.Context, serviceName, envKey string) (string, error)
	DeleteAll(ctx context.Context, serviceName string) error
}

Secrets stores signing secrets in envelope encryption.

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service owns webhook CRUD and the delivery workers.

func NewService

func NewService(d Deps) *Service

NewService builds a Service. Call Run to start delivery.

func (*Service) Create

func (s *Service) Create(ctx context.Context, in Input) (store.EventWebhook, string, error)

Create validates and stores a webhook and returns it with its signing secret, which is shown once and never readable afterwards.

func (*Service) Delete

func (s *Service) Delete(ctx context.Context, id string) error

Delete removes a webhook, its delivery log and its secret.

func (*Service) Deliveries

func (s *Service) Deliveries(ctx context.Context, webhookID string, limit int) ([]store.EventWebhookDelivery, error)

Deliveries lists a webhook's newest deliveries.

func (*Service) Dropped

func (s *Service) Dropped() int64

Dropped reports how many events were discarded because the buffer was full.

func (*Service) Emit

func (s *Service) Emit(e Event)

Emit queues an event without blocking the caller. When the intake buffer is full the event is dropped and counted, never waited on.

func (*Service) Get

func (s *Service) Get(ctx context.Context, id string) (store.EventWebhook, error)

Get returns one webhook.

func (*Service) List

func (s *Service) List(ctx context.Context) ([]store.EventWebhook, error)

List returns every webhook.

func (*Service) Replay

func (s *Service) Replay(ctx context.Context, deliveryID string) (store.EventWebhookDelivery, error)

Replay puts a delivery back in the queue with a fresh attempt budget.

func (*Service) RotateSecret

func (s *Service) RotateSecret(ctx context.Context, id string) (string, error)

RotateSecret issues a new signing secret and returns it once.

func (*Service) Run

func (s *Service) Run(ctx context.Context)

Run fans events out to delivery rows and sends due deliveries until ctx ends.

func (*Service) Summary

func (s *Service) Summary(ctx context.Context, id string) (Counts, error)

Summary tallies a webhook's recent deliveries.

func (*Service) Test

func (s *Service) Test(ctx context.Context, id string) (int, error)

Test sends one probe event synchronously and reports the result.

func (*Service) Update

func (s *Service) Update(ctx context.Context, id string, p Patch) (store.EventWebhook, error)

Update applies a patch.

type Store

type Store interface {
	SaveEventWebhook(ctx context.Context, w store.EventWebhook) error
	UpdateEventWebhook(ctx context.Context, w store.EventWebhook) error
	GetEventWebhook(ctx context.Context, id string) (store.EventWebhook, error)
	ListEventWebhooks(ctx context.Context) ([]store.EventWebhook, error)
	DeleteEventWebhook(ctx context.Context, id string) error
	SaveEventDelivery(ctx context.Context, d store.EventWebhookDelivery) error
	UpdateEventDelivery(ctx context.Context, d store.EventWebhookDelivery) error
	GetEventDelivery(ctx context.Context, id string) (store.EventWebhookDelivery, error)
	ListDueEventDeliveries(ctx context.Context, now string, limit int) ([]store.EventWebhookDelivery, error)
	ListEventDeliveries(ctx context.Context, webhookID string, limit int) ([]store.EventWebhookDelivery, error)
	DeleteEventDeliveriesOlderThan(ctx context.Context, cutoff string) (int64, error)
}

Store is the persistence surface; *store.DB satisfies it.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL