Documentation
¶
Index ¶
- Variables
- func ValidIdempotencyKey(key string) bool
- type Attempt
- type BatchItem
- type BatchRequest
- type ClaimedDelivery
- type Endpoint
- type EndpointAudit
- type EndpointChange
- type Event
- type EventFilter
- type EventPage
- type Histogram
- type IngestionReceipt
- type Investigation
- type MetricsSnapshot
- type Outcome
- type ReplayBatch
- type ReplayRequest
- type ReplayResult
- type ReplaySelection
- type RetentionResult
- type Store
- func (s *Store) Authenticate(ctx context.Context, hash []byte, now time.Time) (auth.Principal, error)
- func (s *Store) ChangeEndpoint(ctx context.Context, endpointID string, change EndpointChange, now time.Time) (Endpoint, error)
- func (s *Store) CheckMasterKey(ctx context.Context, box *secret.Box) error
- func (s *Store) ClaimAvailable(ctx context.Context, workerID string, now time.Time, lease time.Duration, ...) ([]ClaimedDelivery, error)
- func (s *Store) Close()
- func (s *Store) Complete(ctx context.Context, claim ClaimedDelivery, workerID string, now time.Time, ...) (bool, error)
- func (s *Store) CreateEndpoint(ctx context.Context, endpoint Endpoint, secretCiphertext []byte) error
- func (s *Store) CreateEvent(ctx context.Context, event Event, payload []byte, attemptID string) error
- func (s *Store) CreatePrincipal(ctx context.Context, p auth.Principal, now time.Time) error
- func (s *Store) EndpointExists(ctx context.Context, endpointID string) (bool, error)
- func (s *Store) GetBatch(ctx context.Context, batchID string) (ReplayBatch, error)
- func (s *Store) GetEndpoint(ctx context.Context, endpointID string) (Endpoint, error)
- func (s *Store) GetEvent(ctx context.Context, eventID string) (Event, error)
- func (s *Store) IngestEvent(ctx context.Context, event Event, payload []byte, ...) (IngestionReceipt, error)
- func (s *Store) IssueCredential(ctx context.Context, principalID, credentialID string, hash []byte, ...) error
- func (s *Store) ListAttempts(ctx context.Context, eventID string) ([]Attempt, error)
- func (s *Store) ListDeadLetters(ctx context.Context, after string) ([]Event, error)
- func (s *Store) ListEndpointAudit(ctx context.Context, endpointID string, after int64) ([]EndpointAudit, error)
- func (s *Store) ListEndpoints(ctx context.Context, after string) ([]Endpoint, error)
- func (s *Store) Metrics(ctx context.Context, now time.Time) (MetricsSnapshot, error)
- func (s *Store) Migrate(ctx context.Context, now time.Time) error
- func (s *Store) PreviewBatch(ctx context.Context, input BatchRequest, now time.Time) (ReplayBatch, error)
- func (s *Store) Ready(ctx context.Context) error
- func (s *Store) Replay(ctx context.Context, eventID string, input ReplayRequest, now time.Time) (ReplayResult, error)
- func (s *Store) Retain(ctx context.Context, now time.Time, days, limit int, apply bool) (RetentionResult, error)
- func (s *Store) RevokeCredential(ctx context.Context, credentialID string, now time.Time) error
- func (s *Store) RotateMasterKey(ctx context.Context, old, next *secret.Box, now time.Time, apply bool) (int, error)
- func (s *Store) RunBatch(ctx context.Context, batchID, principalID string, now time.Time) (ReplayBatch, error)
- func (s *Store) SearchEvents(ctx context.Context, f EventFilter, after string, limit int) (EventPage, error)
Constants ¶
This section is empty.
Variables ¶
var ErrConflict = errors.New("conflicting replay")
var ErrEndpointConflict = errors.New("endpoint version or rotation precondition failed")
var ErrIdempotencyConflict = errors.New("idempotency key conflicts with accepted event")
var ErrIdempotencyExpired = errors.New("idempotency receipt expired during request")
var ErrInvalidBatch = errors.New("invalid recovery selection")
var ErrInvalidSearch = errors.New("invalid search filters or cursor")
var ErrMasterKey = errors.New("master key does not match database")
var ErrNotFound = errors.New("not found")
var LatencyBuckets = []float64{0.005, 0.025, 0.1, 0.5, 1, 2, 5, 10, 30, 60}
Functions ¶
func ValidIdempotencyKey ¶
Types ¶
type Attempt ¶
type Attempt struct {
RetryBaseSeconds int `json:"retry_base_seconds"`
RetryCapSeconds int `json:"retry_cap_seconds"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
EndpointVersion *int64 `json:"endpoint_version,omitempty"`
SigningVersion *int64 `json:"signing_version,omitempty"`
ReplayPrincipalID *string `json:"replay_principal_id,omitempty"`
TraceParent string `json:"trace_parent,omitempty"`
AttemptNumber int `json:"attempt_number"`
CycleAttempt int `json:"cycle_attempt"`
MaxAttempts int `json:"max_attempts"`
AvailableAt time.Time `json:"available_at"`
Retryable *bool `json:"retryable,omitempty"`
ReplayOf *string `json:"replay_of,omitempty"`
ReplayRequestID *string `json:"replay_request_id,omitempty"`
ReplayActor *string `json:"replay_actor,omitempty"`
ReplayReason *string `json:"replay_reason,omitempty"`
ID string `json:"id"`
EventID string `json:"event_id"`
State string `json:"state"`
ClaimCount int `json:"claim_count"`
LastStartedAt *time.Time `json:"last_started_at,omitempty"`
CompletedAt *time.Time `json:"completed_at,omitempty"`
ResponseStatus *int `json:"response_status,omitempty"`
ErrorCode *string `json:"error_code,omitempty"`
ErrorMessage *string `json:"error_message,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type BatchRequest ¶
type BatchRequest struct {
RequestID string `json:"request_id"`
Reason string `json:"reason"`
Events []ReplaySelection `json:"events"`
PrincipalID string `json:"-"`
Actor string `json:"-"`
}
type ClaimedDelivery ¶
type ClaimedDelivery struct {
RetryBaseSeconds int
RetryCapSeconds int
ExpiresAt *time.Time
EndpointVersion int64
SigningVersion int64
TraceParent string
QueuedAt time.Time
AvailableAt time.Time
CycleAttempt int
LeaseUntil time.Time
AttemptID string
EventID string
EventType string
Payload []byte
EndpointID string
EndpointURL string
SecretCiphertext []byte
ClaimCount int
}
type Endpoint ¶
type Endpoint struct {
Version int64 `json:"version"`
Paused bool `json:"paused"`
SigningVersion int64 `json:"signing_version"`
RetiringSigningVersion *int64 `json:"retiring_signing_version,omitempty"`
RetireAfter *time.Time `json:"retire_after,omitempty"`
RetryBaseSeconds int `json:"retry_base_seconds"`
RetryCapSeconds int `json:"retry_cap_seconds"`
EventTTLSeconds int `json:"event_ttl_seconds"`
CreatedBy string `json:"created_by,omitempty"`
MaxAttempts int `json:"max_attempts"`
ConcurrencyLimit int `json:"concurrency_limit"`
RateLimit int `json:"rate_limit"`
ID string `json:"id"`
URL string `json:"url"`
CreatedAt time.Time `json:"created_at"`
}
type EndpointAudit ¶
type EndpointChange ¶
type EventFilter ¶
type EventPage ¶
type EventPage struct {
Events []Investigation `json:"events"`
NextAfter string `json:"next_after,omitempty"`
}
type IngestionReceipt ¶
IngestionReceipt is the original acceptance, not the event's current state.
type Investigation ¶
type Investigation struct {
Event
AttemptID string `json:"attempt_id"`
AttemptNumber int `json:"attempt_number"`
NextAttemptAt *time.Time `json:"next_attempt_at,omitempty"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
Paused bool `json:"paused"`
FailureCode string `json:"failure_code,omitempty"`
FailureSummary string `json:"failure_summary,omitempty"`
ResponseStatus *int `json:"response_status,omitempty"`
}
type MetricsSnapshot ¶
type MetricsSnapshot struct {
WorkersRecent int64
WorkerPollAgeSeconds float64
WorkerCompletionAgeSeconds float64
DatabaseBytes int64
Events int64
Claims int64
Recoveries int64
Retries int64
Replays int64
Queue map[string]int64
States map[string]int64
Completed map[string]int64
OldestReadySeconds float64
Latency map[string]Histogram
}
type ReplayBatch ¶
type ReplayRequest ¶
type ReplayResult ¶
type ReplaySelection ¶
type RetentionResult ¶
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
func (*Store) Authenticate ¶
func (*Store) ChangeEndpoint ¶
func (s *Store) ChangeEndpoint(ctx context.Context, endpointID string, change EndpointChange, now time.Time) (Endpoint, error)
ChangeEndpoint shares the claim lock. A committed pause prevents later claims; claims committed before it keep their captured destination and signing key.
func (*Store) CheckMasterKey ¶
CheckMasterKey binds even an empty database to its wrapping key. On upgrade, every existing endpoint must decrypt before the marker can be initialized.
func (*Store) ClaimAvailable ¶
func (s *Store) ClaimAvailable(ctx context.Context, workerID string, now time.Time, lease time.Duration, limit int) ([]ClaimedDelivery, error)
ClaimAvailable reserves endpoint capacity and rate permits in the same transaction as attempt leases. All workers share these PostgreSQL counters.
func (*Store) Complete ¶
func (s *Store) Complete(ctx context.Context, claim ClaimedDelivery, workerID string, now time.Time, outcome Outcome) (bool, error)
Complete fences every result with the claim generation and an unexpired lease. A failed result and its successor commit together or neither does.
func (*Store) CreateEndpoint ¶
func (*Store) CreateEvent ¶
func (s *Store) CreateEvent(ctx context.Context, event Event, payload []byte, attemptID string) error
CreateEvent atomically records the exact payload bytes and its first attempt.
func (*Store) CreatePrincipal ¶
func (*Store) EndpointExists ¶
func (*Store) GetEndpoint ¶
func (*Store) IngestEvent ¶
func (s *Store) IngestEvent(ctx context.Context, event Event, payload []byte, attemptID, principalID, key string) (IngestionReceipt, error)
IngestEvent reserves a scoped key and commits event + attempt in the same transaction. The unique index serializes concurrent submissions of that key.
func (*Store) IssueCredential ¶
func (*Store) ListAttempts ¶
func (*Store) ListDeadLetters ¶
ListDeadLetters returns only events whose latest attempt exhausted its budget.
func (*Store) ListEndpointAudit ¶
func (*Store) ListEndpoints ¶
func (*Store) Metrics ¶
Metrics reads transactional cumulative totals and retained-state gauges from one snapshot. The HTTP caller supplies a deadline, never stale zeroes.
func (*Store) PreviewBatch ¶
func (s *Store) PreviewBatch(ctx context.Context, input BatchRequest, now time.Time) (ReplayBatch, error)
PreviewBatch freezes a bounded explicit selection without scheduling delivery. Reusing its ID with the same creator, reason, and set returns durable progress.
func (*Store) Replay ¶
func (s *Store) Replay(ctx context.Context, eventID string, input ReplayRequest, now time.Time) (ReplayResult, error)
Replay requires the current failed attempt as a precondition. Its request ID makes repeated submissions safe even after the replay has finished.
func (*Store) Retain ¶
func (s *Store) Retain(ctx context.Context, now time.Time, days, limit int, apply bool) (RetentionResult, error)
Retain deletes bounded groups in separate transactions. One event's complete history is indivisible; the caller's context bounds unusually large histories. Counts are committed progress (or candidate counts when apply=false).
func (*Store) RevokeCredential ¶
RevokeCredential is idempotent and commits the revocation with its audit row.
func (*Store) RotateMasterKey ¶
func (s *Store) RotateMasterKey(ctx context.Context, old, next *secret.Box, now time.Time, apply bool) (int, error)
RotateMasterKey requires all API and worker processes to be stopped. Table locking protects the transaction, not already-running processes' cached keys.
func (*Store) RunBatch ¶
func (s *Store) RunBatch(ctx context.Context, batchID, principalID string, now time.Time) (ReplayBatch, error)
RunBatch commits at most ten items per call. Only the creating principal can confirm/resume; every HTTP call reauthenticates. No job continues in background.
func (*Store) SearchEvents ¶
func (s *Store) SearchEvents(ctx context.Context, f EventFilter, after string, limit int) (EventPage, error)
SearchEvents uses immutable creation time and UUID as a keyset. State is live, not a snapshot across pages. No payload, key, URL, or raw error is selected.