hitlworker

package
v1.1.0 Latest Latest
Warning

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

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

Documentation

Overview

Package hitlworker runs the periodic sweep that finalizes pending_review holds whose TTL has elapsed. Outbound holds become sent (auto-approved) or review_expired_rejected; inbound holds become review_expired_approved (released to the agent) or review_expired_rejected — per the owning agent's hitl_expiration_action column. Message content remains retained in both cases.

Index

Constants

View Source
const DefaultBatchSize = 100

DefaultBatchSize caps how many rows one sweep will try to finalize. The partial index on (approval_expires_at) WHERE status='pending_review' keeps the list query cheap regardless of total table size.

Variables

This section is empty.

Functions

This section is empty.

Types

type HITLMaintenanceArgs

type HITLMaintenanceArgs struct{}

HITLMaintenanceArgs drives the periodic HITL TTL sweep. No fields — the worker sweeps every expired hold each run.

func (HITLMaintenanceArgs) Kind

func (HITLMaintenanceArgs) Kind() string

type MaintenanceJobs

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

MaintenanceJobs is the jobs.Registrar for the HITL TTL sweep: it contributes the MaintenanceWorker and a periodic that fires it on QueueMaintenance. No enqueuer needed — the schedule is the only trigger.

func NewMaintenanceJobs

func NewMaintenanceJobs(sweeper Sweeper) *MaintenanceJobs

NewMaintenanceJobs builds the registrar around a Sweeper (the *Worker).

func (*MaintenanceJobs) RegisterJobs

func (m *MaintenanceJobs) RegisterJobs(w *river.Workers) []*river.PeriodicJob

RegisterJobs adds the maintenance worker + its periodic schedule. Mirrors the webhook janitor + inbound retention periodics: routed to QueueMaintenance, no UniqueOpts (River's periodic scheduler already inserts at most one per interval and a completed run must not dedup-block the next), RunOnStart:false (first sweep after one interval — a conscious minor change from the old ticker's immediate first sweep, consistent with the other periodics; the per-row store operations are idempotent + cross-replica-safe so scheduling is the only concern). Implements jobs.Registrar.

type MaintenanceWorker

type MaintenanceWorker struct {
	river.WorkerDefaults[HITLMaintenanceArgs]
	// contains filtered or unexported fields
}

MaintenanceWorker runs the TTL sweep once per scheduled job. Any sweep error is logged and swallowed (Work returns nil) so a transient DB blip never spins River's retry machinery for a best-effort idempotent sweep — the next interval picks it up. Mirrors webhookdelivery.MaintenanceWorker.

func NewMaintenanceWorker

func NewMaintenanceWorker(sweeper Sweeper) *MaintenanceWorker

NewMaintenanceWorker builds the worker around a Sweeper. Exported so tests can drive Work directly (RegisterJobs builds an identical one).

func (*MaintenanceWorker) Timeout

Timeout caps the sweep's runtime. River's client default is 1 minute. Auto-approve enqueues onto QueueOutbound instead of blocking, so a bounded timeout safely protects slots in the shared maintenance pool.

func (*MaintenanceWorker) Work

type ManagedUnsubscribeIssuer

type ManagedUnsubscribeIssuer interface {
	Issue(ctx context.Context, userID, agentID, recipient string) (string, error)
}

type OutboundEnqueuer

type OutboundEnqueuer interface {
	EnqueueSendTx(ctx context.Context, tx pgx.Tx, messageID string) (int64, error)
}

OutboundEnqueuer inserts an outbound_send job (QueueOutbound) in the caller's transaction. Satisfied by *outboundsend.Jobs. The sweep hands an approved outbound send to the queue-first pipeline — transitioning the hold to review_expired_approved + delivery_status='accepted' and enqueuing — instead of blocking on Sender.Send. Self-sends never use it (they loopback).

type Sweeper

type Sweeper interface {
	RunOnce(ctx context.Context) error
}

Sweeper runs one TTL-expiration sweep of both hold queues (outbound holds + inbound review holds). Satisfied by *Worker — the River worker just drives its RunOnce on a schedule instead of a hand-rolled time.Ticker.

type WebSocketHub

type WebSocketHub interface {
	IsConnected(agentID string) bool
	Send(agentID string, msg []byte) bool
}

type Worker

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

Worker runs the TTL sweep. Construct with New; its RunOnce is driven on a schedule by the River maintenance periodic (see maintenance.go).

func New

func New(store *identity.Store, sender *outbound.Sender, usageTracker usage.UsageTracker, fromDomain string) *Worker

New constructs a Worker. fromDomain is the deployment's outbound from-domain (cfg.OutboundSMTP.FromDomain) — used by the self-send loopback branch to stamp the synthetic Message-ID / Received headers the same way internal/agent does on the user-driven approve path. Pass "" if the deployment has no outbound relay configured; the loopback path falls back to "e2a.local" for the host portion.

func (*Worker) RunOnce

func (w *Worker) RunOnce(ctx context.Context) error

RunOnce performs a single sweep of both queues (outbound holds, then inbound review holds). This is the sweep body the River maintenance periodic drives on a schedule (see maintenance.go); it's also called directly by tests for deterministic behavior. Returns nil — both sweeps log and swallow their own per-row/query errors internally (a transient DB blip should not spin River's retry machinery); the error return satisfies the Sweeper interface.

func (*Worker) SetManagedUnsubscribeIssuer

func (w *Worker) SetManagedUnsubscribeIssuer(i ManagedUnsubscribeIssuer)

func (*Worker) SetOutboundEnqueuer

func (w *Worker) SetOutboundEnqueuer(e OutboundEnqueuer)

SetOutboundEnqueuer wires the mandatory outbound send enqueuer. Two-phase wiring: pass the *outboundsend.Jobs pointer; its shared River client is injected later via the jobs client's SetEnqueuer.

func (*Worker) SetOutbox

func (w *Worker) SetOutbox(o webhookpub.Outbox)

SetOutbox wires the transactional outcome-event writer for providerless local delivery. Production uses the same unconditional outbox as all other message triggers.

func (*Worker) SetPublisher

func (w *Worker) SetPublisher(p webhookpub.Publisher)

SetPublisher wires the webhook publisher used to emit review-resolution events on TTL auto-resolution. Without it the sweep transitions rows silently.

func (*Worker) SetWebSocketHub

func (w *Worker) SetWebSocketHub(h WebSocketHub)

Jump to

Keyboard shortcuts

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