queue

package
v0.4.5 Latest Latest
Warning

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

Go to latest
Published: Oct 21, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package queue implements the local, durable half of diagnostic delivery.

The queue deliberately stores opaque ciphertext bytes. Encryption and decryption are supplied through EnvelopeCodec, so this package never opens a network connection, calls a KMS, or depends on a concrete envelope type.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidConfig       = errors.New("invalid diagnostic queue configuration")
	ErrInvalidRequest      = errors.New("invalid diagnostic queue request")
	ErrCodecRequired       = errors.New("diagnostic queue requires an envelope codec for plaintext")
	ErrCorrupt             = errors.New("diagnostic queue state is corrupt")
	ErrUnsafePath          = errors.New("diagnostic queue path is unsafe")
	ErrQueueFull           = errors.New("diagnostic queue is full")
	ErrByteQuota           = errors.New("diagnostic queue byte quota exceeded")
	ErrIdempotencyConflict = errors.New("diagnostic queue idempotency conflict")
	ErrNotFound            = errors.New("diagnostic queue item not found")
	ErrExpired             = errors.New("diagnostic queue item expired")
	ErrEmpty               = errors.New("diagnostic queue is empty")
	ErrPaused              = errors.New("diagnostic queue is paused")
	ErrClosed              = errors.New("diagnostic queue is closed")
	ErrWorkerRunning       = errors.New("diagnostic queue worker is already running")
	ErrInvalidState        = errors.New("invalid diagnostic queue item state")
	ErrAttemptsExceeded    = errors.New("diagnostic queue retry attempts exceeded")
	ErrCleanup             = errors.New("diagnostic queue cleanup failed")
	ErrUnsupportedSchema   = errors.New("unsupported diagnostic queue state schema")
)
View Source
var (
	ErrQuotaExceeded = ErrByteQuota
	ErrQueueClosed   = ErrClosed
	ErrStateCorrupt  = ErrCorrupt
	ErrIdempotency   = ErrIdempotencyConflict
)

Functions

This section is empty.

Types

type CleanupPolicy

type CleanupPolicy struct {
	DeletePlaintextAfterSeal   bool
	DeleteCiphertextOnSuccess  bool
	DeleteCiphertextOnFailure  bool
	DeleteCiphertextOnExpiry   bool
	RetainSuccessfulCiphertext bool
	DeleteOnSuccess            bool
	DeleteOnFailure            bool
	DeleteOnExpiry             bool
}

type Codec

type Codec = EnvelopeCodec

type CodecFunc

type CodecFunc struct {
	SealFn SealFunc
	OpenFn OpenFunc
}

func (CodecFunc) Open

func (f CodecFunc) Open(ctx context.Context, ciphertext []byte) ([]byte, error)

func (CodecFunc) Seal

func (f CodecFunc) Seal(ctx context.Context, plaintext []byte) ([]byte, error)

type Config

type Config struct {
	Root, Directory, Path      string
	RootDir, QueueDir, DataDir string
	Codec                      any
	MaxItems                   int
	MaxBytes                   int64
	MaxQueueItems              int
	MaxQueueBytes              int64
	TTL                        time.Duration
	HistoryTTL                 time.Duration
	RetryDelay                 time.Duration
	MaxAttempts                int
	Clock                      func() time.Time
	Cleanup                    CleanupPolicy
	DeletePolicy               DeletePolicy
	DeletePlaintextAfterSeal   bool
	DeleteCiphertextOnSuccess  bool
	DeleteCiphertextOnFailure  bool
	DeleteCiphertextOnExpiry   bool
	RetainSuccessfulCiphertext bool
}

type DeletePolicy

type DeletePolicy string
const (
	DeleteNever             DeletePolicy = "never"
	DeleteAfterSuccess      DeletePolicy = "after_success"
	DeleteAfterFailure      DeletePolicy = "after_failure"
	DeleteAfterExpiry       DeletePolicy = "after_expiry"
	DeleteAfterTerminal     DeletePolicy = "after_terminal"
	DeleteCiphertextSuccess DeletePolicy = DeleteAfterSuccess
)

type DeliveryFunc

type DeliveryFunc = Handler

type EnqueueRequest

type EnqueueRequest = Request

type Entry

type Entry = Item

type EnvelopeCodec

type EnvelopeCodec interface {
	Seal(context.Context, []byte) ([]byte, error)
	Open(context.Context, []byte) ([]byte, error)
}

EnvelopeCodec is the narrow dependency used when a caller submits plaintext. Implementations normally adapt a diagnostics envelope package.

type EnvelopeOpener

type EnvelopeOpener interface {
	Open(context.Context, []byte) ([]byte, error)
}

type EnvelopeSealer

type EnvelopeSealer interface {
	Seal(context.Context, []byte) ([]byte, error)
}

type EnvelopeStore

type EnvelopeStore interface {
	PutEnvelope(context.Context, []byte) error
	GetEnvelope(context.Context, string) ([]byte, error)
	DeleteEnvelope(context.Context, string) error
}

EnvelopeStore is an optional integration boundary for callers that keep envelope serialization elsewhere. Store never invokes it.

type Handler

type Handler func(context.Context, Item) error

type Item

type Item struct {
	ID, UploadID                      string
	TenantID, PluginID, PluginVersion string
	Target, LeaseID, IdempotencyKey   string
	PolicyEpoch                       uint64
	ObjectDigest                      string
	Digest                            string
	Ciphertext, Envelope              []byte
	Payload, EncryptedPayload         []byte
	Size, Bytes                       int64
	State                             State
	Attempt, MaxAttempts              int
	CreatedAt, ExpiresAt, UpdatedAt   time.Time
	AvailableAt                       time.Time
	LastError                         string
}

type Metadata

type Metadata struct {
	TenantID      string
	PluginID      string
	PluginVersion string
	Target        string
	LeaseID       string
	PolicyEpoch   uint64
}

type OpenFunc

type OpenFunc func(context.Context, []byte) ([]byte, error)

func (OpenFunc) Open

func (f OpenFunc) Open(ctx context.Context, ciphertext []byte) ([]byte, error)

type Queue

type Queue = Store

func NewQueue

func NewQueue(args ...any) (*Queue, error)

type QueueConfig

type QueueConfig = Config

type Receipt

type Receipt struct {
	ID, UploadID         string
	ObjectDigest, Digest string
	State                State
	Size                 int64
	Attempt, MaxAttempts int
	CreatedAt, ExpiresAt time.Time
}

type Record

type Record = Item

type Request

type Request struct {
	ID, UploadID                           string
	TenantID, PluginID, PluginVersion      string
	Target, LeaseID, IdempotencyKey        string
	PolicyEpoch                            uint64
	Plaintext                              []byte
	Payload, Data                          []byte
	Ciphertext, Envelope, EncryptedPayload []byte
	CreatedAt, ExpiresAt                   time.Time
	TTL                                    time.Duration
	MaxAttempts                            int
	Metadata                               Metadata
}

type SealFunc

type SealFunc func(context.Context, []byte) ([]byte, error)

func (SealFunc) Seal

func (f SealFunc) Seal(ctx context.Context, plaintext []byte) ([]byte, error)

type State

type State string
const (
	StateQueued     State = "queued"
	StateRetrying   State = "retrying"
	StateProcessing State = "processing"
	StateUploading  State = StateProcessing
	StateClaimed    State = StateProcessing
	StatePending    State = StateQueued
	StateCompleted  State = "completed"
	StateFailed     State = "failed"
	StateExpired    State = "expired"
	StateCanceled   State = "canceled"
)

type Stats

type Stats struct {
	Pending, Queued, Retrying, Processing int
	Completed, Failed, Expired, Canceled  int
	Items                                 int
	Bytes                                 int64
	Paused                                bool
	Corrupt                               int
	LastError                             error
}

type Status

type Status = Item

type Store

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

func New

func New(args ...any) (*Store, error)

func NewStore

func NewStore(args ...any) (*Store, error)

func Open

func Open(args ...any) (*Store, error)

func (*Store) Cancel

func (s *Store) Cancel(ctx context.Context, id string, reason ...string) error

func (*Store) Claim

func (s *Store) Claim(ctx context.Context) (*Item, error)

Claim atomically selects the oldest item nearest to TTL, marks it as processing, increments Attempt, and returns a private ciphertext copy.

func (*Store) Close

func (s *Store) Close() error

func (*Store) Complete

func (s *Store) Complete(ctx context.Context, id string, success bool) error

func (*Store) CompleteWithError

func (s *Store) CompleteWithError(ctx context.Context, id string, success bool, cause error) error

func (*Store) Delete

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

func (*Store) Enqueue

func (s *Store) Enqueue(ctx context.Context, req Request) (Receipt, error)

Enqueue seals plaintext through the configured codec, or accepts an opaque encrypted field already present on req. The caller's plaintext slice is not modified; an internal copy is wiped after Seal returns.

func (*Store) EnqueueBytes

func (s *Store) EnqueueBytes(ctx context.Context, idempotencyKey string, ciphertext []byte) (Receipt, error)

func (*Store) EnqueueEncrypted

func (s *Store) EnqueueEncrypted(ctx context.Context, req Request, ciphertext []byte) (Receipt, error)

EnqueueEncrypted admits bytes that have already been sealed by an envelope adapter. It never invokes the codec and is the fastest WAF-safe path.

func (*Store) EnqueuePlaintext

func (s *Store) EnqueuePlaintext(ctx context.Context, req Request, plaintext []byte) (Receipt, error)

func (*Store) Get

func (s *Store) Get(ctx context.Context, id string) (Item, error)

func (*Store) IsPaused

func (s *Store) IsPaused() bool

func (*Store) Len

func (s *Store) Len() int

func (*Store) List

func (s *Store) List(ctx context.Context) ([]Item, error)

func (*Store) Next

func (s *Store) Next(ctx context.Context) (*Item, error)

func (*Store) ObjectPath

func (s *Store) ObjectPath(digest string) string

ObjectPath returns the canonical content-addressed ciphertext path. It is useful for backup tooling and intentionally never exposes plaintext.

func (*Store) Pause

func (s *Store) Pause(ctxs ...context.Context) error

func (*Store) Paused

func (s *Store) Paused() bool

func (*Store) Pending

func (s *Store) Pending() int

func (*Store) Purge

func (s *Store) Purge(ctx context.Context) error

Purge removes terminal history whose retention window has elapsed. It is intentionally explicit so callers can schedule it without a background timer storm.

func (*Store) Put

func (s *Store) Put(ctx context.Context, req Request) (Receipt, error)

func (*Store) ReadEnvelope

func (s *Store) ReadEnvelope(ctx context.Context, id string) ([]byte, error)

ReadEnvelope returns a copy of the persisted ciphertext. It never invokes EnvelopeCodec.Open, so plaintext cannot accidentally cross this boundary.

func (*Store) Resume

func (s *Store) Resume(ctxs ...context.Context) error

func (*Store) Retry

func (s *Store) Retry(ctx context.Context, id string, reason ...string) error

func (*Store) Run

func (s *Store) Run(ctx context.Context, handler Handler) error

func (*Store) SetPaused

func (s *Store) SetPaused(paused bool) error

func (*Store) Snapshot

func (s *Store) Snapshot(ctx context.Context) ([]Item, error)

func (*Store) Start

func (s *Store) Start(ctx context.Context, handler Handler) error

Start launches exactly one local worker. Handler errors are converted into durable retry/failure states; they are not returned on the caller's request goroutine and never panic the WAF process.

func (*Store) StartWorker

func (s *Store) StartWorker(ctx context.Context, handler Handler) error

func (*Store) Stats

func (s *Store) Stats() Stats

func (*Store) Status

func (s *Store) Status(ctx context.Context, id string) (Item, error)

func (*Store) Stop

func (s *Store) Stop() error

Stop cancels the worker and waits for it to leave. It is safe to call more than once and does not delete pending durable items.

func (*Store) Submit

func (s *Store) Submit(ctx context.Context, req Request) (Receipt, error)

func (*Store) WorkerError

func (s *Store) WorkerError() error

type StoreConfig

type StoreConfig = Config

Jump to

Keyboard shortcuts

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