push

package
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: May 25, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package push implements a push job queue for devices that are not connected to SSE at the time an event is published.

Index

Constants

This section is empty.

Variables

View Source
var ErrRelayUnavailable = errors.New("relay unavailable")

ErrRelayUnavailable is returned when the relay is unreachable (network error, 5xx response, or context cancellation).

Functions

This section is empty.

Types

type Dispatcher

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

Dispatcher is a ticker goroutine that reads push_queue, builds notifications via Templates, and sends them to the push relay.

func NewDispatcher

func NewDispatcher(deps DispatcherDeps) *Dispatcher

NewDispatcher creates a dispatcher with the given dependencies and defaults.

func (*Dispatcher) Run

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

Run starts the dispatcher loop. Blocks until ctx is cancelled.

type DispatcherDeps

type DispatcherDeps struct {
	Queue       model.PushQueue
	Events      model.EventStore
	Devices     model.DeviceStore
	Relay       RelayClient
	Templates   TemplateResolver
	Clock       func() time.Time
	Logger      *slog.Logger
	Interval    time.Duration
	BatchSize   int
	MaxAttempts int
}

DispatcherDeps holds dependencies for the push notification dispatcher.

type HTTPRelayClientConfig

type HTTPRelayClientConfig struct {
	BaseURL    string
	InstanceID string
	Secret     []byte
	Timeout    time.Duration
	Clock      func() time.Time
	Logger     *slog.Logger
}

HTTPRelayClientConfig holds parameters for the relay HTTP client.

type NilRelayClient

type NilRelayClient struct{}

NilRelayClient is a no-op implementation used when the push section is not configured.

func (NilRelayClient) DeleteRegistration

func (NilRelayClient) DeleteRegistration(_ context.Context, _ string) error

func (NilRelayClient) Push

func (NilRelayClient) UpsertRegistration

type RelayClient

type RelayClient interface {
	Push(ctx context.Context, req pushproto.PushRequest) (pushproto.PushResponse, error)
	UpsertRegistration(ctx context.Context, deviceID string, r pushproto.RegistrationRequest) error
	DeleteRegistration(ctx context.Context, deviceID string) error
}

RelayClient is the interface for instance-to-push-relay communication.

func NewHTTPRelayClient

func NewHTTPRelayClient(cfg HTTPRelayClientConfig) RelayClient

NewHTTPRelayClient creates an HTTP implementation of RelayClient.

type SQLitePushQueue

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

SQLitePushQueue implements model.PushQueue on top of SQLite.

func NewSQLitePushQueue

func NewSQLitePushQueue(db *sql.DB) *SQLitePushQueue

NewSQLitePushQueue creates a SQLitePushQueue backed by the given database.

func (*SQLitePushQueue) DeleteDelivered

func (q *SQLitePushQueue) DeleteDelivered(ctx context.Context, cutoff time.Time) (int64, error)

DeleteDelivered deletes completed jobs (delivered_at OR dropped_at) whose completion timestamp is before cutoff. Returns the number of deleted rows.

func (*SQLitePushQueue) Drop

func (q *SQLitePushQueue) Drop(ctx context.Context, id int64, reason string) error

Drop marks a job as permanently failed (dropped_at = now, dropped_reason = reason).

func (*SQLitePushQueue) Enqueue

func (q *SQLitePushQueue) Enqueue(ctx context.Context, tx *sql.Tx, deviceID string, eventSeq int64) error

Enqueue enqueues a single job within the given transaction. Sets created_at to the current time, next_attempt_at = created_at, attempts = 0.

func (*SQLitePushQueue) MarkDelivered

func (q *SQLitePushQueue) MarkDelivered(ctx context.Context, id int64) error

MarkDelivered marks a job as delivered (delivered_at = now).

func (*SQLitePushQueue) MarkFailed

func (q *SQLitePushQueue) MarkFailed(ctx context.Context, id int64, errText string, nextAttempt time.Time) error

MarkFailed increments attempts, saves the error text, and schedules the next attempt no earlier than nextAttempt.

func (*SQLitePushQueue) NextBatch

func (q *SQLitePushQueue) NextBatch(ctx context.Context, limit int) ([]model.PushJob, error)

NextBatch returns up to limit pending jobs (delivered_at IS NULL and dropped_at IS NULL) whose next_attempt_at has already passed. Ordered by next_attempt_at ASC, id ASC. limit <= 0 means no limit.

type TemplateResolver

type TemplateResolver interface {
	Resolve(ctx context.Context, ev *model.Event) (*pushproto.PushRequest, bool, error)
}

TemplateResolver builds a push request from a domain event.

type Templates

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

Templates builds push notifications for events following the decision table from the spec.

func NewTemplates

func NewTemplates(timezone string) *Templates

NewTemplates creates a Templates instance. timezone is an IANA timezone name (e.g. "Europe/Moscow") used for deadline formatting. Empty or unknown value → time.UTC.

func (*Templates) Resolve

Resolve parses the event and returns a PushRequest if the event is push-worthy. ok=false means the event should not be sent as a push notification.

Jump to

Keyboard shortcuts

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