events

package
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Sep 2, 2026 License: AGPL-3.0 Imports: 14 Imported by: 0

Documentation

Overview

Package events owns the gateway's outbound webhook surface: the event names, the signed envelope, and delivery to configured endpoints with bounded retry. Nothing pushes until configuration names an endpoint, and a payload carries identifiers and states only — never a provider credential, gateway key material, or prompt and response content.

Index

Constants

View Source
const (
	// TypeBudgetExhausted fires when a budget refuses a request: the
	// window's spend or token meter is spent and the caller drew a 402.
	TypeBudgetExhausted = "budget.exhausted"
	// TypeJobCompleted fires once when an asynchronous job produced its
	// asset.
	TypeJobCompleted = "job.completed"
	// TypeJobFailed fires once when an asynchronous job ended without an
	// asset.
	TypeJobFailed = "job.failed"
	// TypeJobCancelled fires once when a job's owner stopped it.
	TypeJobCancelled = "job.cancelled"
	// TypeProviderHealthChanged fires when a provider's status-page
	// indicator moved: an incident opened, worsened, or cleared.
	TypeProviderHealthChanged = "provider.health.changed"
	// TypeKeyCreated fires when the admin surface issues a gateway API
	// key. The payload names the key; it never carries the token.
	TypeKeyCreated = "key.created"
	// TypeKeyDeleted fires when the admin surface revokes a gateway API
	// key.
	TypeKeyDeleted = "key.deleted"
)

Event type names. Each follows concept.verb, the naming the audit trail's actions use, so an operator reads one vocabulary across both surfaces.

View Source
const SignatureHeader = "X-Starport-Signature"

SignatureHeader carries the delivery's HMAC so a receiver can prove the body came from this gateway and arrived unchanged.

#nosec G101 -- An HTTP header name, not a credential.

Variables

This section is empty.

Functions

func RedactEndpoint

func RedactEndpoint(endpoint string) string

RedactEndpoint strips the userinfo and the query from a receiver URL. A receiver often authenticates through a token in either place, and the admin surface shows where deliveries go, not how they authenticate. A value that does not parse as a URL redacts to its scheme and host portion only.

func Sign

func Sign(secret, body []byte) string

Sign computes the header value for one delivery body: "sha256=" and the lowercase hex HMAC-SHA256 of the body under the shared secret.

func TypeForJobState

func TypeForJobState(state string) string

TypeForJobState maps a terminal job state onto its event name. The job seam reports states without naming events, so the mapping lives here with the rest of the vocabulary. An unknown state maps to TypeJobFailed: a receiver told nothing about an ended job is worse than one told the conservative verdict.

func Types

func Types() []string

Types lists every event name the gateway emits, in the order the operator guide documents them.

func Verify

func Verify(secret, body []byte, header string) bool

Verify reports whether header is the valid signature for body under secret. The comparison is constant-time. It is what a receiver runs, and the operator guide's sample encodes the same check.

Types

type Dispatcher

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

Dispatcher delivers each emitted event to every configured endpoint, signed, from its own goroutine. An emit never blocks the caller: the emit sites sit on the request path and the poller's pass, and a webhook receiver must not be able to slow either.

A nil *Dispatcher emits nothing, so every emit site holds one unconditionally. That is the unconfigured deployment: no endpoint, no outbound push.

func NewDispatcher

func NewDispatcher(endpoints []string, secret string, options Options) *Dispatcher

NewDispatcher builds a dispatcher for the configured endpoints. It returns nil when endpoints is empty: webhooks stay off until configuration names a receiver.

func (*Dispatcher) Close

func (d *Dispatcher) Close(ctx context.Context) error

Close delivers what is already queued and stops the worker. The context bounds the wait.

func (*Dispatcher) Emit

func (d *Dispatcher) Emit(eventType string, data map[string]string)

Emit queues one event for delivery and returns immediately. A full queue or a closed dispatcher drops the event and counts a dead letter.

func (*Dispatcher) Stats

func (d *Dispatcher) Stats() Stats

Stats reports the delivery state. A nil dispatcher is the unconfigured deployment and reports no endpoints and nothing queued.

type Event

type Event struct {
	// ID names this event. A receiver deduplicates redeliveries on it.
	ID string `json:"id"`
	// Type is one of the Type constants above.
	Type string `json:"type"`
	// Time is when the gateway observed the fact, RFC 3339 UTC.
	Time string `json:"time"`
	// Data is the typed payload: identifiers, scopes, and states.
	Data map[string]string `json:"data"`
}

Event is the envelope one delivery carries, encoded as one JSON object. Data holds short identifier and state strings only.

type Options

type Options struct {
	// MaxPending bounds the undelivered queue. An emit against a full
	// queue drops the event and OnDeadLetter counts it.
	MaxPending int
	// OnDeadLetter observes every event that will never deliver: dropped
	// at a full queue, or spent through every attempt at an endpoint.
	// Nil observes nothing.
	OnDeadLetter func(count int)
	// Now replaces the clock. A test states its own times.
	Now func() time.Time
}

Options tune a dispatcher. The zero value selects the defaults.

type Stats

type Stats struct {
	// Endpoints lists the configured receivers, redacted.
	Endpoints []string
	// QueueDepth counts the events waiting for delivery.
	QueueDepth int
	// QueueCapacity is the pending bound the queue drops at.
	QueueCapacity int
	// DeadLetters counts every event that will never deliver since start.
	DeadLetters int64
}

Stats is the delivery state the admin surface reports. Endpoints carries each receiver with its credentials and query removed, so the summary never repeats a secret a receiver URL embeds.

Jump to

Keyboard shortcuts

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