arbiter-core-0.1.0.0
arbiter-core
Safe HaskellNone
LanguageGHC2024

Arbiter.Core.Operations

Description

Internal to the arbiter packages. Not covered by the PVP.

The job queue operations, over any MonadArbiter backend.

Synopsis

Job insertion

insertJob :: forall m payload. (JobPayload payload, MonadArbiter m) => SchemaName -> TableName -> JobWrite payload -> m (Maybe (JobRead payload))Source #

Insert a job, returning it with its database-generated fields. Nothing when an IgnoreDuplicate key already exists, or a ReplaceDuplicate one names a job that is in flight (claimed under a live lease), force-cancel-flagged, has a different parent, or has children (DLQ children count). Parent and rollup state come from insertJobTree.

insertJobTreeNodeStamped :: forall m payload. (JobPayload payload, MonadArbiter m) => SchemaName -> TableName -> TraceStamp payload -> Maybe Int64 -> Maybe Value -> Bool -> JobWrite payload -> m (Maybe (JobRead payload))Source #

Internal tree insertion path for engine-owned parent and suspension state.

insertJobTreeLeavesStamped :: forall m payload. (JobPayload payload, MonadArbiter m) => SchemaName -> TableName -> TraceStamp payload -> Int64 -> [JobWrite payload] -> m [JobRead payload]Source #

Batch-insert direct tree leaves under one parent.

spawnChildren :: forall m payload. (JobPayload payload, MonadArbiter m) => SchemaName -> TableName -> JobRead payload -> NonEmpty (JobWrite payload) -> m (NonEmpty (JobRead payload))Source #

Insert children under a job this worker holds, making it a rollup finalizer. Ack it in the same transaction.

insertJobsBatch :: forall m payload. (JobPayload payload, MonadArbiter m) => SchemaName -> TableName -> [JobWrite payload] -> m [JobRead payload]Source #

Arguments

:: forall m payload. (JobPayload payload, MonadArbiter m) 
=> SchemaName 
-> TableName 
-> [JobWrite payload]

Jobs to insert

-> m [JobRead payload] 

insertJob over a batch in one round trip, returning the jobs inserted or replaced. Jobs sharing a dedup key within the batch collapse the way sequential insertJob calls would.

insertJobsBatch_ :: forall m payload. (JobPayload payload, MonadArbiter m) => SchemaName -> TableName -> [JobWrite payload] -> m Int64Source #

insertJobsBatch discarding the rows, returning the rows affected, dedup replacements included.

type TraceStamp payload = JobWrite payload -> JobWrite payloadSource #

What an insert path puts on its jobs, carrying the ambient trace context.

traceStamp :: MonadIO m => m (TraceStamp payload)Source #

The stamp for the context in scope. One read covers every job inserted under it.

Results and rollup state

insertResult :: MonadArbiter m => SchemaName -> TableName -> Int64 -> Int64 -> Value -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Parent job id

-> Int64

Child job id

-> Value

Encoded result value

-> m Int64 

Upsert a child's result, keyed by (parent_id, child_id). A second write replaces the first. Its foreign key cascades on the parent's ack.

insertResultsBatch :: MonadArbiter m => SchemaName -> TableName -> [(Int64, Int64, Value)] -> m Int64Source #

insertResult for several (parent id, child id, result) rows in one statement. Each row is an upsert.

getResultsByParent :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m (Map Int64 Value)Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Parent job id

-> m (Map Int64 Value) 

A parent's child results, keyed by child id.

getDLQChildErrorsByParent :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m (Map Int64 Text)Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Parent job id

-> m (Map Int64 Text) 

The last errors of a parent's children in the DLQ, keyed by child id. Children with no recorded error are left out.

persistParentState :: MonadArbiter m => SchemaName -> TableName -> Int64 -> Value -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Job id

-> Value

The pre-populated parent state to persist

-> m Int64 

Snapshot results into parent_state before DLQ move.

getParentStateSnapshot :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m (Maybe Value)Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Job id

-> m (Maybe Value) 

Read a job's raw parent_state snapshot, which a DLQ-retried finalizer comes back carrying.

readChildResultsRaw :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m (Map Int64 Value, Map Int64 Text, Maybe Value, Map Int64 Text)Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Parent job id

-> m (Map Int64 Value, Map Int64 Text, Maybe Value, Map Int64 Text) 

Read child results, DLQ errors, and the parent_state snapshot for a rollup finalizer in a single query. Returns (childId->result, childId->error, parentStateSnapshot, dlqRowId->error).

mergeRawChildResults :: Map Int64 Value -> Map Int64 Text -> Maybe Value -> Map Int64 (Either Text Value)Source #

Merge DLQ errors, child results and the snapshot, left-biased in that order.

Claiming

claimNextVisibleJobs :: forall m payload. (JobPayload payload, MonadArbiter m) => SchemaName -> TableName -> Int -> NominalDiffTime -> m [JobRead payload]Source #

Claim up to maxJobs visible jobs, one per group. Stamps the anonymous claimant.

claimNextVisibleJobsAs :: forall m payload. (JobPayload payload, MonadArbiter m) => SchemaName -> TableName -> Int -> NominalDiffTime -> UUID -> m [JobRead payload]Source #

claimNextVisibleJobs under a given worker id.

claimNextVisibleJobsBatched :: forall m payload. (JobPayload payload, MonadArbiter m) => SchemaName -> TableName -> Int -> Int -> NominalDiffTime -> m [NonEmpty (JobRead payload)]Source #

claimNextVisibleJobs claiming at most maxBatches batches of up to batchSize jobs. Each batch is one group, or ungrouped jobs batched together. Stamps the anonymous claimant.

data JobStatementsSource #

A pool's statements, rendered once. A call binds only its parameters.

mkJobStatements :: JobPayload payload => SchemaName -> TableName -> Int -> Int -> NominalDiffTime -> UUID -> JobStatementsSource #

Arguments

:: JobPayload payload 
=> SchemaName 
-> TableName 
-> Int

Batch size

-> Int

Pool size

-> NominalDiffTime

Visibility timeout

-> UUID

Bound as the claim's claimed_by

-> JobStatements 

Assemble a pool's statements once. Batch size 1 is the single-job claim.

singleJobBatchSize :: IntSource #

The mkJobStatements batch size of a claim that takes one job per batch.

noStagedCapacities :: IntSource #

The mkJobStatements pool size that stages no claim statement. Each claim renders its own.

claimJobsCached :: forall m payload. (JobPayload payload, MonadArbiter m) => JobStatements -> Int -> m ([JobRead payload], [RejectedRow payload])Source #

claimNextVisibleJobsAs over a pool's staged statements. Returns the rejected rows for deadLetterRejected.

claimJobsBatchedCached :: forall m payload. (JobPayload payload, MonadArbiter m) => JobStatements -> Int -> m ([NonEmpty (JobRead payload)], [RejectedRow payload])Source #

claimNextVisibleJobsBatched over a pool's staged statements.

type RejectedRow payload = (JobRead (Stored payload), Text)Source #

A claimed row its payload type rejected, with the decode error.

deadLetterRejected :: MonadArbiter m => RejectedRow payload -> m Int64Source #

Move a rejected row to the DLQ with its decode error. Returns the number of rows moved. Zero means the claim was voided first.

Row decoding

decodeRow :: FromJSON payload => JobRead (Stored payload) -> Either Text (JobRead payload)Source #

Decode a row's stored payload, or the reason the type rejects it.

typedRow :: (FromJSON payload, MonadArbiter m) => JobRead (Stored payload) -> m (JobRead payload)Source #

decodeRow, throwing ParsingException for a payload the type rejects.

typedDLQRow :: (FromJSON payload, MonadArbiter m) => DLQJob (Stored payload) -> m (DLQJob payload)Source #

typedRow over a DLQ entry's job snapshot.

typedArchiveRow :: (FromJSON payload, MonadArbiter m) => ArchiveJob (Stored payload) -> m (ArchiveJob payload)Source #

typedRow over an archive entry's job snapshot.

Rate-limit operations

addRateLimitTokens :: MonadArbiter m => SchemaName -> RateLimitKey -> Double -> m ()Source #

Add tokens to a key's bucket, clamped to [0, max]. A no-op without a policy. For operator top-ups and manually-refilled policies.

pruneRateLimitBuckets :: MonadArbiter m => SchemaName -> NominalDiffTime -> m Int64Source #

Delete full, idle rate-limit buckets. Returns the number pruned.

resetRateLimitBuckets :: MonadArbiter m => SchemaName -> Text -> m Int64Source #

Refill every bucket under a prefix to full. Returns the number refilled.

wakeThrottledJobs :: MonadArbiter m => SchemaName -> [TableName] -> Text -> m Int64Source #

Make a prefix's throttled jobs claimable again across the given queue tables, in one statement. Returns the number woken.

wakeThrottledJobsForKey :: MonadArbiter m => SchemaName -> [TableName] -> RateLimitKey -> m Int64Source #

Wake one key's throttled jobs across the given tables, in one statement. Returns the number woken.

listRateLimitPolicies :: MonadArbiter m => SchemaName -> [TableName] -> m [RateLimitPolicyView]Source #

List every policy with its default/override params, bucket aggregates, and live throttled count across the given queue tables.

getRateLimitPolicy :: MonadArbiter m => SchemaName -> [TableName] -> Text -> m (Maybe RateLimitPolicyView)Source #

One prefix's policy view with bucket aggregates and live throttled count.

rateLimitPolicyExists :: MonadArbiter m => SchemaName -> Text -> m BoolSource #

Whether a rate-limit policy exists for a prefix.

listRateLimitBuckets :: MonadArbiter m => SchemaName -> Text -> Int -> Int -> m [RateLimitBucketView]Source #

List a prefix's buckets with effective max and fill fraction, paginated.

updateRateLimitPolicyOverrides :: MonadArbiter m => SchemaName -> Text -> RateLimitPolicyUpdate -> m Int64Source #

Set or clear a policy's override params. Returns rows affected (0 if absent).

Concurrency operations

listConcurrencyPolicies :: MonadArbiter m => SchemaName -> m [ConcurrencyPolicyView]Source #

List every concurrency policy with its default/override limit and live key and in-flight aggregates.

getConcurrencyPolicy :: MonadArbiter m => SchemaName -> Text -> m (Maybe ConcurrencyPolicyView)Source #

One prefix's concurrency policy view with live aggregates. Nothing when the prefix has no policy.

concurrencyPolicyExists :: MonadArbiter m => SchemaName -> Text -> m BoolSource #

Whether a concurrency policy exists for a prefix.

listConcurrencyKeys :: MonadArbiter m => SchemaName -> Text -> Int -> Int -> m [ConcurrencyKeyView]Source #

List a prefix's keys with effective cap and fill fraction, paginated.

updateConcurrencyPolicyOverrides :: MonadArbiter m => SchemaName -> Text -> ConcurrencyPolicyUpdate -> m Int64Source #

Apply a concurrency policy's override-limit patch (retunes every key under the prefix). Returns rows affected.

pruneConcurrencyKeys :: MonadArbiter m => SchemaName -> [TableName] -> m Int64Source #

Delete drained concurrency rows with no live job across the given tables. Returns the number pruned. A key whose advisory try-lock is contended is skipped until the next pass.

reconcileConcurrencyCounts :: MonadArbiter m => SchemaName -> [TableName] -> m Int64Source #

Lock the count rows, then recount those keys under the lock. A key seeded after the lock pass is left to its triggers. Seeds a count row for a live key that has none. Returns the rows repaired.

reconcileConcurrencyCountsIfStale :: MonadArbiter m => SchemaName -> [TableName] -> m Int64Source #

Rebuild the counts when a crash truncated the UNLOGGED table. Returns the rows it repaired.

reconcileAndPruneConcurrency :: MonadArbiter m => SchemaName -> [TableName] -> m Int64Source #

Reconcile then prune, skipped when no concurrency key exists. Returns the rows repaired and pruned.

Ack, nack and visibility

ackJob :: MonadArbiter m => SchemaName -> TableName -> JobRead payload -> m Int64Source #

Ack a completed job. Deletes a childless job, suspends a parent whose children are still running, and wakes a parent whose last child finished. A child's ack takes the parent's advisory lock. Returns 1, or 0 for a job gone or reclaimed.

statementsAck :: JobStatements -> AckStatementsSource #

The pool's ack statements.

data AckStatementsSource #

A table's ack statements, rendered once. A call binds only its parameters.

ackJobWith :: MonadArbiter m => AckStatements -> JobRead payload -> m Int64Source #

ackJob inside the caller's transaction, over staged statements.

ackJobsBatchWith :: MonadArbiter m => AckStatements -> [JobRead payload] -> m [Int64]Source #

ackJobsBatch inside the caller's transaction, over staged statements.

ackJobsBatch :: MonadArbiter m => SchemaName -> TableName -> [JobRead payload] -> m [Int64]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> [JobRead payload] 
-> m [Int64]

Ids acked (deleted or suspended). Gone or reclaimed jobs are absent.

ackJob over a batch in one statement, locking the distinct parents to serialize with concurrent sibling acks.

archivesOnAck :: JobRead payload -> BoolSource #

Whether acking this job tees it into the archive (positive archiveFor).

setVisibilityTimeout :: MonadArbiter m => SchemaName -> TableName -> NominalDiffTime -> JobRead payload -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> NominalDiffTime

Timeout in seconds

-> JobRead payload 
-> m Int64

Rows updated. 0 for a row that is gone, reclaimed, or suspended.

Extend a job's visibility timeout. Matches the claim token only.

setVisibilityTimeoutBatch :: MonadArbiter m => SchemaName -> TableName -> NominalDiffTime -> [JobRead payload] -> m [VisibilityUpdateInfo]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> NominalDiffTime

Timeout in seconds

-> [JobRead payload] 
-> m [VisibilityUpdateInfo]

One status record per job targeted.

setVisibilityTimeout over a batch, reporting each row through VisibilityUpdateInfo. Each row must also match its holder. A row whose row lock or group lock is busy is not extended.

data VisibilityUpdateInfoSource #

What a batch visibility update found for one job.

Constructors

VisibilityUpdateInfo 

Fields

Instances

Instances details
Eq VisibilityUpdateInfo Source # 
Instance details

Defined in Arbiter.Core.Operations

Generic VisibilityUpdateInfo Source # 
Instance details

Defined in Arbiter.Core.Operations

Associated Types

type Rep VisibilityUpdateInfo 
Instance details

Defined in Arbiter.Core.Operations

type Rep VisibilityUpdateInfo = D1 ('MetaData "VisibilityUpdateInfo" "Arbiter.Core.Operations" "arbiter-core-0.1.0.0-inplace" 'False) (C1 ('MetaCons "VisibilityUpdateInfo" 'PrefixI 'True) ((S1 ('MetaSel ('Just "vuiJobId") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 JobId) :*: (S1 ('MetaSel ('Just "vuiWasHeartbeated") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Bool) :*: S1 ('MetaSel ('Just "vuiCurrentDbClaimSeq") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe ClaimSeq)))) :*: (S1 ('MetaSel ('Just "vuiCancelRequested") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Bool) :*: (S1 ('MetaSel ('Just "vuiSuspended") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Bool) :*: S1 ('MetaSel ('Just "vuiClaimedBy") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe UUID))))))
Show VisibilityUpdateInfo Source # 
Instance details

Defined in Arbiter.Core.Operations

type Rep VisibilityUpdateInfo Source # 
Instance details

Defined in Arbiter.Core.Operations

type Rep VisibilityUpdateInfo = D1 ('MetaData "VisibilityUpdateInfo" "Arbiter.Core.Operations" "arbiter-core-0.1.0.0-inplace" 'False) (C1 ('MetaCons "VisibilityUpdateInfo" 'PrefixI 'True) ((S1 ('MetaSel ('Just "vuiJobId") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 JobId) :*: (S1 ('MetaSel ('Just "vuiWasHeartbeated") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Bool) :*: S1 ('MetaSel ('Just "vuiCurrentDbClaimSeq") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe ClaimSeq)))) :*: (S1 ('MetaSel ('Just "vuiCancelRequested") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Bool) :*: (S1 ('MetaSel ('Just "vuiSuspended") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Bool) :*: S1 ('MetaSel ('Just "vuiClaimedBy") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe UUID))))))

updateJobForRetry :: MonadArbiter m => SchemaName -> TableName -> NominalDiffTime -> Text -> JobRead payload -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> NominalDiffTime

Backoff, rounded up to whole seconds

-> Text

Error message

-> JobRead payload 
-> m Int64 

Park a failed job for its retry backoff, recording the error. Returns 0 for a job another worker holds or a suspended job.

nackJob :: MonadArbiter m => SchemaName -> TableName -> Maybe NominalDiffTime -> JobRead payload -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Maybe NominalDiffTime

Delay in seconds

-> JobRead payload 
-> m Int64 

Soft-nack a job. Hands back the attempt the claim consumed and records no failure. A delay parks the job for that long, rounded up to whole seconds. Without one, it is reprocessed once its lease lapses. Returns 0 for a job another worker holds, a suspended job, or a released claim.

nackJobsBatch :: MonadArbiter m => SchemaName -> TableName -> Maybe NominalDiffTime -> [JobRead payload] -> m [Int64]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Maybe NominalDiffTime

Delay in seconds

-> [JobRead payload] 
-> m [Int64] 

nackJob over a batch in one statement, returning the ids nacked. Jobs another worker holds, suspended jobs and released claims are absent.

Parent and tree locks

lockJobParents :: MonadArbiter m => SchemaName -> TableName -> [Maybe Int64] -> m ()Source #

Take the advisory lock of every distinct parent named, ascending, before any row lock the caller goes on to take.

lockJobRootsAndParents :: MonadArbiter m => SchemaName -> TableName -> [Int64] -> m ()Source #

Take every advisory lock a cascade cancellation will acquire, in one ordered pass before locking its rows. A branch root may itself have a parent.

lockJobTrees :: MonadArbiter m => SchemaName -> TableName -> [Int64] -> m TreesLockedSource #

Lock every job named and all of its descendants, in one descending pass, then their groups and their parents' groups.

lockJobTreesFromRoot :: MonadArbiter m => SchemaName -> TableName -> [Int64] -> m TreesLockedSource #

Apply lockJobTrees to the complete tree of each named job. Use these locks before tree cancellation.

data TreesLockedSource #

Proof that this transaction ran lockJobTrees or lockJobTreesFromRoot, so it holds the rows and their groups before it wakes a parent.

data TreeLocksSource #

Whether the caller already took the parent and tree locks over its whole set.

Constructors

TakeLocks

The callee takes the parent and tree locks.

LocksHeld TreesLocked

The caller holds the locks already.

Dead-letter queue operations

moveToDLQ :: MonadArbiter m => TreeLocks -> SchemaName -> TableName -> Text -> JobRead payload -> m Int64Source #

Arguments

:: MonadArbiter m 
=> TreeLocks 
-> SchemaName 
-> TableName 
-> Text

Error message (the final error that caused the DLQ move)

-> JobRead payload 
-> m Int64 

Move a job to the DLQ, cascading a rollup parent's descendants with it and waking the parent of a child. A held job is moved too. Returns 0 when the job's claim token changed or the job was deleted after the read.

moveToDLQFields :: MonadArbiter m => TreeLocks -> DLQMove -> SchemaName -> TableName -> Text -> Int64 -> Int64 -> Maybe Int64 -> Bool -> m Int64Source #

Arguments

:: MonadArbiter m 
=> TreeLocks 
-> DLQMove 
-> SchemaName 
-> TableName 
-> Text

Error message (the final error that caused the DLQ move)

-> Int64

Job id

-> Int64

Claim token (for the optimistic move check)

-> Maybe Int64

Parent id, if a child

-> Bool

Whether the job is a rollup finalizer

-> m Int64 

moveToDLQ driven by scalar fields, for callers without a typed JobRead.

moveToDLQBatch :: MonadArbiter m => SchemaName -> TableName -> [(JobRead payload, Text)] -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> [(JobRead payload, Text)]

List of (job, error message) pairs

-> m Int64 

moveToDLQ over a batch, each job under its own error message. Jobs another worker reclaimed are skipped. Returns the number moved.

retryFromDLQ :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m (Maybe (JobRead (Stored payload)))Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

DLQ primary key (dlqPrimaryKey)

-> m (Maybe (JobRead (Stored payload))) 

Retry the whole DLQ tree that holds a DLQ row, with a fresh attempt count. The dedup key is left behind. Returns the restored job for that row. Nothing when the row is gone or the root's parent no longer exists.

retryFromDLQWithPayload :: forall m payload. (JobPayload payload, MonadArbiter m) => SchemaName -> TableName -> Int64 -> Maybe payload -> m (Maybe (JobRead (Stored payload)))Source #

Arguments

:: forall m payload. (JobPayload payload, MonadArbiter m) 
=> SchemaName 
-> TableName 
-> Int64

DLQ primary key (dlqPrimaryKey)

-> Maybe payload 
-> m (Maybe (JobRead (Stored payload))) 

retryFromDLQ with an optional replacement payload. The columns the payload derives are derived again from it. Nothing retries the stored payload.

dlqJobExists :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m BoolSource #

Whether a DLQ row with the given DLQ primary key exists.

listDLQJobs :: MonadArbiter m => SchemaName -> TableName -> Int -> Int -> m [DLQJob (Stored payload)]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int

Limit

-> Int

Offset

-> m [DLQJob (Stored payload)] 

List DLQ jobs, most recently failed first.

deleteDLQJob :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

DLQ primary key (dlqPrimaryKey)

-> m Int64 

Delete a DLQ job, resuming its parent when no child of it is left in the main queue.

deleteDLQJobsBatch :: MonadArbiter m => SchemaName -> TableName -> [Int64] -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> [Int64]

DLQ primary keys (dlqPrimaryKey)

-> m Int64 

Delete multiple jobs from the dead letter queue, resuming any parents left childless. Returns the total number of DLQ jobs deleted.

purgeDLQ :: MonadArbiter m => SchemaName -> [TableName] -> m (Int64, [Text])Source #

Delete one batch of DLQ jobs per given queue that failed longer ago than the queue's DLQ retention (setQueueDLQRetention), resuming any parents left childless. A queue without a retention is skipped. Returns the rows deleted and the queues that failed.

retryFromDLQBatch :: MonadArbiter m => SchemaName -> TableName -> [Int64] -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> [Int64]

DLQ primary keys (dlqPrimaryKey)

-> m Int64 

retryFromDLQ over several DLQ rows, each tree in its own transaction. A row restored with an earlier row's tree is skipped. Returns the number of rows whose retry restored a tree.

retryDLQFiltered :: MonadArbiter m => SchemaName -> TableName -> [JobFilter] -> m Int64Source #

retryFromDLQBatch over every DLQ row the filters match when it starts, oldest first.

Archive operations

listArchiveJobs :: MonadArbiter m => SchemaName -> TableName -> Int -> Int -> m [ArchiveJob (Stored payload)]Source #

List archived jobs (most recent first).

listArchiveFiltered :: MonadArbiter m => SchemaName -> TableName -> [JobFilter] -> Maybe ArchiveSortColumn -> Maybe SortDir -> Int -> Int -> m [ArchiveJob (Stored payload)]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> [JobFilter] 
-> Maybe ArchiveSortColumn 
-> Maybe SortDir 
-> Int

Limit

-> Int

Offset

-> m [ArchiveJob (Stored payload)] 

List archived (completed) jobs with composable filters and a typed sort (defaulting to most recent first).

getArchiveJobById :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m (Maybe (ArchiveJob (Stored payload)))Source #

Fetch a single archived job by its original job id.

listArchiveJobsByGroup :: MonadArbiter m => SchemaName -> TableName -> Text -> Int -> Int -> m [ArchiveJob (Stored payload)]Source #

List archived jobs in a group, most recent first.

countArchiveFiltered :: MonadArbiter m => SchemaName -> TableName -> [JobFilter] -> m Int64Source #

Count archived jobs with composable filters.

purgeArchives :: MonadArbiter m => SchemaName -> [TableName] -> m (Int64, [Text])Source #

Purge one batch of expired archived jobs per given queue. Each row uses its archive_expires_at value. Returns the rows purged and the queues that failed.

deleteArchiveJob :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m Int64Source #

Delete one archived job by its archive primary key. Returns rows deleted.

deleteArchiveJobsBatch :: MonadArbiter m => SchemaName -> TableName -> [Int64] -> m Int64Source #

Delete archived jobs by archive primary key. Returns rows deleted.

reEnqueueFromArchive :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m (Maybe (JobRead (Stored payload)))Source #

Re-enqueue an archived job as a fresh standalone job, keeping the archive row. Returns the new job, or Nothing when the archive row no longer exists.

reEnqueueFromArchiveWithPayload :: forall m payload. (JobPayload payload, MonadArbiter m) => SchemaName -> TableName -> Int64 -> Maybe payload -> m (Maybe (JobRead (Stored payload)))Source #

reEnqueueFromArchive with an optional replacement payload. The columns the payload derives are derived again from it. The archive row keeps its payload. Nothing re-enqueues the stored payload.

updateArchiveResult :: MonadArbiter m => SchemaName -> TableName -> Int64 -> Value -> m Int64Source #

Store a completed root job's result on its archive row. No-ops when the job was not archived. Returns rows updated.

updateArchiveResultsBatch :: MonadArbiter m => SchemaName -> TableName -> [(Int64, Value)] -> m Int64Source #

updateArchiveResult for several (job id, result) pairs in one statement.

Filtered query operations

data JobFilterSource #

A narrowing predicate on a job listing. Filters combine with AND.

Constructors

FilterGroupKey Text

Jobs in this group.

FilterParentId Int64

Children of this parent.

FilterRootsOnly

Jobs with no parent.

FilterStatus JobStatus

Jobs with this derived status. Matches nothing on the DLQ or archive.

FilterId Int64

The row with this primary key.

FilterJobId Int64

The row with this original job id. On the main table, the row with this id.

FilterClaimedBy UUID

Jobs claimed by this worker.

FilterKind Text

Jobs with this kind label.

FilterPayloadText Text

Jobs whose payload text holds this substring, ignoring case.

FilterErrorText Text

Jobs whose last error holds this substring, ignoring case.

FilterRateLimitPrefix Text

Jobs under this rate-limit prefix.

FilterConcurrencyPrefix Text

Jobs under this concurrency prefix.

FilterInsertedAfter UTCTime

Jobs inserted at or after this time.

FilterInsertedBefore UTCTime

Jobs inserted before this time.

FilterCompletedAfter UTCTime

Jobs completed at or after this time. Matches nothing outside the archive.

FilterCompletedBefore UTCTime

Jobs completed before this time. Matches nothing outside the archive.

Instances

Instances details
Eq JobFilter Source # 
Instance details

Defined in Arbiter.Core.Sql.Jobs

Show JobFilter Source # 
Instance details

Defined in Arbiter.Core.Sql.Jobs

data FilterTableSource #

The table a JobFilter narrows.

Instances

Instances details
Eq FilterTable Source # 
Instance details

Defined in Arbiter.Core.Sql.Jobs

Show FilterTable Source # 
Instance details

Defined in Arbiter.Core.Sql.Jobs

data SortDirSource #

Sort direction.

Constructors

SortAsc

Ascending.

SortDesc

Descending.

Instances

Instances details
Eq SortDir Source # 
Instance details

Defined in Arbiter.Core.Sql.Jobs

Methods

(==) :: SortDir -> SortDir -> Bool#

(/=) :: SortDir -> SortDir -> Bool#

Bounded SortDir Source # 
Instance details

Defined in Arbiter.Core.Sql.Jobs

Enum SortDir Source # 
Instance details

Defined in Arbiter.Core.Sql.Jobs

Show SortDir Source # 
Instance details

Defined in Arbiter.Core.Sql.Jobs

sortDirName :: SortDir -> TextSource #

A sort direction as a query parameter.

jobSortColumnName :: JobSortColumn -> TextSource #

Underlying SQL column name for a JobSortColumn.

data DLQSortColumnSource #

Sortable columns on the DLQ table. DlqId is the DLQ primary key and DlqJobId the original job id.

Constructors

DlqId

By id, the DLQ primary key.

DlqFailedAt

By failed_at.

DlqJobId

By job_id, the original job id.

DlqPriority

By priority.

DlqAttempts

By attempts.

DlqInsertedAt

By inserted_at.

DlqGroupKey

By group_key.

DlqParentId

By parent_id.

DlqLastAttemptedAt

By last_attempted_at.

dlqSortColumnName :: DLQSortColumn -> TextSource #

The DLQ column a sort key names.

data ArchiveSortColumnSource #

Sortable columns on the archive table. ArchiveId is the archive primary key and ArchiveJobId the original job id.

Constructors

ArchiveId

By id, the archive primary key.

ArchiveCompletedAt

By completed_at.

ArchiveInsertedAt

By inserted_at.

ArchiveJobId

By job_id, the original job id.

ArchiveAttempts

By attempts.

ArchiveGroupKey

By group_key.

ArchiveParentId

By parent_id.

archiveSortColumnName :: ArchiveSortColumn -> TextSource #

The archive column a sort key names.

buildWhereClause :: FilterTable -> [JobFilter] -> Query ()Source #

The WHERE clause a set of filters narrows a listing of one table by. Empty for no filters.

listJobsFiltered :: MonadArbiter m => SchemaName -> TableName -> [JobFilter] -> Int -> Int -> m [JobRead (Stored payload)]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> [JobFilter]

Composable filters

-> Int

Limit

-> Int

Offset

-> m [JobRead (Stored payload)] 

List filtered jobs, newest first.

listJobsFilteredOrdered :: MonadArbiter m => SchemaName -> TableName -> [JobFilter] -> Maybe JobSortColumn -> Maybe SortDir -> Int -> Int -> m [JobRead (Stored payload)]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> [JobFilter]

Composable filters

-> Maybe JobSortColumn

Sort column (defaults to JsId)

-> Maybe SortDir

Sort direction (defaults to SortDesc)

-> Int

Limit

-> Int

Offset

-> m [JobRead (Stored payload)] 

List filtered jobs under an explicit sort spec. Nothing for both sort arguments orders by id DESC.

listJobsWithStatus :: MonadArbiter m => SchemaName -> TableName -> [JobFilter] -> Maybe JobSortColumn -> Maybe SortDir -> Int -> Int -> m [(JobRead (Stored payload), JobStatus)]Source #

listJobsFilteredOrdered that also returns each job's derived status.

countJobsFiltered :: MonadArbiter m => SchemaName -> TableName -> [JobFilter] -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> [JobFilter]

Composable filters

-> m Int64 

Count jobs with composable filters.

listDLQFiltered :: MonadArbiter m => SchemaName -> TableName -> [JobFilter] -> Int -> Int -> m [DLQJob (Stored payload)]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> [JobFilter]

Composable filters

-> Int

Limit

-> Int

Offset

-> m [DLQJob (Stored payload)] 

List filtered DLQ jobs, most recently failed first.

listDLQFilteredOrdered :: MonadArbiter m => SchemaName -> TableName -> [JobFilter] -> Maybe DLQSortColumn -> Maybe SortDir -> Int -> Int -> m [DLQJob (Stored payload)]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> [JobFilter]

Composable filters

-> Maybe DLQSortColumn

Sort column (defaults to DlqFailedAt)

-> Maybe SortDir

Sort direction (defaults to SortDesc)

-> Int

Limit

-> Int

Offset

-> m [DLQJob (Stored payload)] 

List filtered DLQ jobs under an explicit sort spec. Nothing for both sort arguments orders by failed_at DESC.

countDLQFiltered :: MonadArbiter m => SchemaName -> TableName -> [JobFilter] -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> [JobFilter]

Composable filters

-> m Int64 

Count DLQ jobs with composable filters.

listDLQJobsByParent :: MonadArbiter m => SchemaName -> TableName -> Int64 -> Int -> Int -> m [DLQJob (Stored payload)]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Parent job id

-> Int

Limit

-> Int

Offset

-> m [DLQJob (Stored payload)] 

List a parent's children in the DLQ, most recently failed first.

countDLQJobsByParent :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m Int64Source #

Count DLQ jobs matching a parent_id.

Admin operations

listJobs :: MonadArbiter m => SchemaName -> TableName -> Int -> Int -> m [JobRead (Stored payload)]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int

Limit

-> Int

Offset

-> m [JobRead (Stored payload)] 

List jobs, newest first.

getJobById :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m (Maybe (JobRead (Stored payload)))Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Job id

-> m (Maybe (JobRead (Stored payload))) 

Fetch a job by id.

getJobByIdWithStatus :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m (Maybe (JobRead (Stored payload), JobStatus))Source #

getJobById that also returns the job's derived status.

getJobByDedupKey :: MonadArbiter m => SchemaName -> TableName -> Text -> m (Maybe (JobRead (Stored payload)))Source #

Get a single job by its dedup key.

listJobsByGroup :: MonadArbiter m => SchemaName -> TableName -> Text -> Int -> Int -> m [JobRead (Stored payload)]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Text

Group key

-> Int

Limit

-> Int

Offset

-> m [JobRead (Stored payload)] 

A page of a group's jobs, newest first.

jobExists :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m BoolSource #

Whether a job with the given id exists in the table, without decoding it.

listJobsByParent :: MonadArbiter m => SchemaName -> TableName -> Int64 -> Int -> Int -> m [JobRead (Stored payload)]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Parent id

-> Int

Limit

-> Int

Offset

-> m [JobRead (Stored payload)] 

List jobs filtered by parent_id with pagination.

countJobsByParent :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m Int64Source #

Count jobs matching a parent_id.

cancelJob :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Job id

-> m Int64 

Delete a job by id. Returns 0 for a job with children, which cancelJobCascade takes. A deleted child with no siblings left resumes its parent for a completion round.

cancelJobsBatch :: MonadArbiter m => SchemaName -> TableName -> [Int64] -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> [Int64]

Job ids

-> m Int64 

cancelJob over several ids in one transaction. A job with children is skipped. The last sibling cancelled finds the parent childless and resumes it. Locks the union of parents and rows first. Returns the number deleted.

promoteJob :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Job id

-> m Int64

Number of rows updated

Make a delayed or retrying job immediately visible. Refuses an in-flight or suspended job.

rescheduleJob :: MonadArbiter m => SchemaName -> TableName -> Int64 -> UTCTime -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Job id

-> UTCTime

When the job becomes visible

-> m Int64

Number of rows updated

Set when a job next becomes visible. Refuses an in-flight, suspended, force-cancel-flagged or exhausted job.

data QueueStatsSource #

Per-status breakdown of a queue. The per-status counts partition the queue and sum to totalJobs.

Constructors

QueueStats 

Fields

Instances

Instances details
FromJSON QueueStats Source # 
Instance details

Defined in Arbiter.Core.Operations

ToJSON QueueStats Source # 
Instance details

Defined in Arbiter.Core.Operations

Eq QueueStats Source # 
Instance details

Defined in Arbiter.Core.Operations

Generic QueueStats Source # 
Instance details

Defined in Arbiter.Core.Operations

Associated Types

type Rep QueueStats 
Instance details

Defined in Arbiter.Core.Operations

type Rep QueueStats = D1 ('MetaData "QueueStats" "Arbiter.Core.Operations" "arbiter-core-0.1.0.0-inplace" 'False) (C1 ('MetaCons "QueueStats" 'PrefixI 'True) (((S1 ('MetaSel ('Just "totalJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64) :*: (S1 ('MetaSel ('Just "readyJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64) :*: S1 ('MetaSel ('Just "inFlightJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64))) :*: ((S1 ('MetaSel ('Just "scheduledJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64) :*: S1 ('MetaSel ('Just "backoffJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64)) :*: (S1 ('MetaSel ('Just "throttledJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64) :*: S1 ('MetaSel ('Just "suspendedJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64)))) :*: (((S1 ('MetaSel ('Just "cancelledJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64) :*: S1 ('MetaSel ('Just "exhaustedJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64)) :*: (S1 ('MetaSel ('Just "blockedJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64) :*: S1 ('MetaSel ('Just "oldestReadyAgeSeconds") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe Double)))) :*: ((S1 ('MetaSel ('Just "oldestInFlightAgeSeconds") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe Double)) :*: S1 ('MetaSel ('Just "dlqJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64)) :*: (S1 ('MetaSel ('Just "kindCounts") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Map Text Int64)) :*: S1 ('MetaSel ('Just "dlqKindCounts") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Map Text Int64)))))))
Show QueueStats Source # 
Instance details

Defined in Arbiter.Core.Operations

type Rep QueueStats Source # 
Instance details

Defined in Arbiter.Core.Operations

type Rep QueueStats = D1 ('MetaData "QueueStats" "Arbiter.Core.Operations" "arbiter-core-0.1.0.0-inplace" 'False) (C1 ('MetaCons "QueueStats" 'PrefixI 'True) (((S1 ('MetaSel ('Just "totalJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64) :*: (S1 ('MetaSel ('Just "readyJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64) :*: S1 ('MetaSel ('Just "inFlightJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64))) :*: ((S1 ('MetaSel ('Just "scheduledJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64) :*: S1 ('MetaSel ('Just "backoffJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64)) :*: (S1 ('MetaSel ('Just "throttledJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64) :*: S1 ('MetaSel ('Just "suspendedJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64)))) :*: (((S1 ('MetaSel ('Just "cancelledJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64) :*: S1 ('MetaSel ('Just "exhaustedJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64)) :*: (S1 ('MetaSel ('Just "blockedJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64) :*: S1 ('MetaSel ('Just "oldestReadyAgeSeconds") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe Double)))) :*: ((S1 ('MetaSel ('Just "oldestInFlightAgeSeconds") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe Double)) :*: S1 ('MetaSel ('Just "dlqJobs") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64)) :*: (S1 ('MetaSel ('Just "kindCounts") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Map Text Int64)) :*: S1 ('MetaSel ('Just "dlqKindCounts") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Map Text Int64)))))))

queueStatusCounts :: QueueStats -> [(Text, Int64)]Source #

The per-status depths a QueueStats carries, labelled by wire name. Blocked is a stats partition only. A row's own status reads ready.

data QueueOverviewSource #

A landing-overview row: a queue's stats, pause flag and worker counts.

Constructors

QueueOverview 

Fields

Instances

Instances details
FromJSON QueueOverview Source # 
Instance details

Defined in Arbiter.Core.Operations

ToJSON QueueOverview Source # 
Instance details

Defined in Arbiter.Core.Operations

Eq QueueOverview Source # 
Instance details

Defined in Arbiter.Core.Operations

Generic QueueOverview Source # 
Instance details

Defined in Arbiter.Core.Operations

Associated Types

type Rep QueueOverview 
Instance details

Defined in Arbiter.Core.Operations

type Rep QueueOverview = D1 ('MetaData "QueueOverview" "Arbiter.Core.Operations" "arbiter-core-0.1.0.0-inplace" 'False) (C1 ('MetaCons "QueueOverview" 'PrefixI 'True) ((S1 ('MetaSel ('Just "overviewQueue") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text) :*: S1 ('MetaSel ('Just "overviewStats") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 QueueStats)) :*: (S1 ('MetaSel ('Just "overviewQueuePaused") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Bool) :*: (S1 ('MetaSel ('Just "overviewWorkersLive") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64) :*: S1 ('MetaSel ('Just "overviewWorkersPaused") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64)))))
Show QueueOverview Source # 
Instance details

Defined in Arbiter.Core.Operations

type Rep QueueOverview Source # 
Instance details

Defined in Arbiter.Core.Operations

type Rep QueueOverview = D1 ('MetaData "QueueOverview" "Arbiter.Core.Operations" "arbiter-core-0.1.0.0-inplace" 'False) (C1 ('MetaCons "QueueOverview" 'PrefixI 'True) ((S1 ('MetaSel ('Just "overviewQueue") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text) :*: S1 ('MetaSel ('Just "overviewStats") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 QueueStats)) :*: (S1 ('MetaSel ('Just "overviewQueuePaused") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Bool) :*: (S1 ('MetaSel ('Just "overviewWorkersLive") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64) :*: S1 ('MetaSel ('Just "overviewWorkersPaused") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64)))))

getQueueStats :: MonadArbiter m => SchemaName -> TableName -> [Text] -> m QueueStatsSource #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> [Text]

The labels the payload declares. kindCounts covers these labels.

-> m QueueStats 

A queue's per-status counts and backlog ages.

getAllQueueStats :: MonadArbiter m => SchemaName -> [(TableName, [Text])] -> m [QueueOverview]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> [(TableName, [Text])]

Each queue with the labels its payload declares.

-> m [QueueOverview] 

Every queue's stats plus pause state in one query, for the landing overview.

data GroupSummarySource #

One open group, read from the queue's groups summary.

Constructors

GroupSummary 

Fields

listGroups :: MonadArbiter m => SchemaName -> TableName -> Maybe Text -> Int -> Int -> m [GroupSummary]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Maybe Text

Group key

-> Int

Limit

-> Int

Offset

-> m [GroupSummary] 

A page of a queue's open groups, largest first, optionally narrowed to one key.

countGroups :: MonadArbiter m => SchemaName -> TableName -> Maybe Text -> m Int64Source #

The number of open groups listGroups pages through.

Count operations

countJobs :: MonadArbiter m => SchemaName -> TableName -> m Int64Source #

Count every job in a table.

countJobsByGroup :: MonadArbiter m => SchemaName -> TableName -> Text -> m Int64Source #

Count a group's jobs.

countDLQJobs :: MonadArbiter m => SchemaName -> TableName -> m Int64Source #

Count a queue's DLQ jobs.

Parent-child operations

countChildrenBatch :: MonadArbiter m => SchemaName -> TableName -> [Int64] -> m (Map Int64 (Int64, Int64))Source #

Child counts as (total, suspended) per parent id, over a batch. Parents with none are absent.

countDLQChildrenBatch :: MonadArbiter m => SchemaName -> TableName -> [Int64] -> m (Map Int64 Int64)Source #

DLQ child counts per parent id, over a batch. Parents with none are absent.

Job dependency operations

pauseChildren :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Parent job id

-> m Int64 

Suspend every unsuspended visible job in a parent's subtree, lapsed leases included. Jobs with a future visibility (delayed, backoff, throttled, leased) are skipped. Returns the number suspended.

resumeChildren :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Parent job id

-> m Int64 

Resume the suspended jobs in a parent's subtree. A finalizer with children still in the queue stays suspended. Returns the number resumed.

cancelJobCascade :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m [Int64]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Root job id

-> m [Int64] 

Delete a job and every descendant under it, resuming the parent of a root that is itself a child. Returns the ids deleted.

cancelJobTree :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m [Int64]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Any job id in the tree

-> m [Int64] 

Delete a whole job tree, named by any node in it. Walks up to the root, then deletes from there down. The root has no parent to resume. The caller holds lockJobParents and lockJobTreesFromRoot. Returns the ids deleted.

forceCancelJob :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Root job id

-> m Int64 

Cascade-cancel a job subtree. Flags still-live claimed jobs, deletes the rest, and NOTIFYs the queue's cancel channel for every claimed job affected. Returns the number flagged or deleted.

data CancelledScope payloadSource #

Which force-cancel-flagged jobs deleteCancelledJobs deletes.

Constructors

LapsedOnly [Int64]

Jobs that have no live lease. The reaper uses this scope.

HeldBy UUID [JobRead payload]

Jobs that this worker holds, as its claim returned them. Do not use a row from a later read of a flagged job.

deleteCancelledJobs :: MonadArbiter m => SchemaName -> TableName -> CancelledScope payload -> m [Int64]Source #

Delete the force-cancel-flagged jobs in scope and resume the parents that have no children after the delete. Returns the deleted ids.

cancelTokenBump :: Int64Source #

The amount that a force-cancel flag adds to the claim token.

Suspend and resume operations

suspendJob :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Job id

-> m Int64 

Suspend a job, making it unclaimable. Refuses an in-flight job.

resumeJob :: MonadArbiter m => SchemaName -> TableName -> Int64 -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int64

Job id

-> m Int64 

Resume a suspended job. Refuses a finalizer with children still in the main queue.

Groups table operations

data GroupsCursorSource #

Where a queue's next groups pass resumes. The summary window and the emptied scan walk the key space independently.

Constructors

GroupsCursor 

Fields

data GroupsPassSource #

What one queue's groups pass did: the rows it rewrote, whether its missing-summary repair threw, and where the next pass resumes.

Constructors

GroupsPass 

Fields

refreshGroupsForQueue :: MonadArbiter m => SchemaName -> TableName -> Int -> Maybe GroupsCursor -> m GroupsPassSource #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> TableName 
-> Int

Rows this pass covers.

-> Maybe GroupsCursor

Resume past these keys, or start at the first.

-> m GroupsPass 

Recompute the groups table from the main queue, over one bounded batch of rows past the resume cursor. Locks the window's groups rows and the emptied ones (FOR UPDATE SKIP LOCKED), then rewrites them, which deletes the emptied. The rewrite and the missing-summary repair each run in their own transaction, or a savepoint inside the caller's. The caller owns any cross-pool coordination (see runGatedState and refreshAllGroups).

refreshAllGroups :: MonadArbiter m => SchemaName -> [TableName] -> Map TableName GroupsCursor -> m ((Int64, [Text]), Map TableName GroupsCursor)Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> [TableName] 
-> Map TableName GroupsCursor

Where the previous pass left off, per queue.

-> m ((Int64, [Text]), Map TableName GroupsCursor) 

Schema-wide groups refresh over one bounded pass. Under runGatedState, one worker pool runs it per interval and every worker pool resumes from the same cursors. Each queue's rewrite and repair run in their own savepoints. One queue's failure leaves the rest. Its row locks stand until the caller's transaction ends. Returns the rows rewritten, the queue names that failed or whose repair failed, and where each queue resumes.

refreshAllGroupsFully :: MonadArbiter m => SchemaName -> [TableName] -> m (Int64, [Text])Source #

Run refreshGroupsForQueue on each queue at the full batch size until it scans the queue's complete groups table.

Reaper sweeps

sweepExhaustedJobs :: MonadArbiter m => SchemaName -> [TableName] -> m (Int64, [Text])Source #

Sweep exhausted jobs across the given queues. Returns the total moved and the names of queues whose sweep failed.

sweepCancelledJobs :: MonadArbiter m => SchemaName -> [TableName] -> m (Int64, [Text])Source #

Sweep force-cancel-flagged jobs whose lease has lapsed across the given queues. A job under a live lease is left for its holder's cancel handler. Returns the total deleted and the names of queues whose sweep failed.

Cron schedule operations

upsertCronDefault :: MonadArbiter m => SchemaName -> Text -> Text -> Text -> Text -> Maybe Text -> Bool -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> Text

Schedule name

-> Text

Queue name

-> Text

Default cron expression

-> Text

Default overlap policy

-> Maybe Text

Default IANA tz name (Nothing = UTC).

-> Bool

Enabled state for a row this call creates. An existing row keeps its own.

-> m Int64 

Upsert a cron schedule's default expression, overlap policy and timezone. User overrides and the enabled flag stay. queue_name is overwritten on conflict.

listCronSchedules :: MonadArbiter m => SchemaName -> Maybe Text -> m [CronScheduleRow]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> Maybe Text

Queue filter. Nothing returns schedules for all queues.

-> m [CronScheduleRow] 

List cron schedules ordered by name, optionally filtered by queue.

getCronScheduleByName :: MonadArbiter m => SchemaName -> Text -> m (Maybe CronScheduleRow)Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> Text

Schedule name

-> m (Maybe CronScheduleRow) 

Get a single cron schedule by name.

updateCronSchedule :: MonadArbiter m => SchemaName -> Text -> CronScheduleUpdate -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> Text

Schedule name

-> CronScheduleUpdate 
-> m Int64 

Patch a cron schedule. Returns rows affected, 0 for a name that is not there or an empty patch.

touchCronChecked :: MonadArbiter m => SchemaName -> [Text] -> UTCTime -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> [Text]

Schedule names

-> UTCTime

Watermark (the minute the scheduler is advancing to)

-> m Int64 

Advance last_checked_at to the supplied watermark for the given cron schedule names. The watermark is the minute boundary the scheduler finished evaluating. The column never moves back.

tryFireCronGate :: MonadArbiter m => SchemaName -> Text -> UTCTime -> m BoolSource #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> Text

Schedule name

-> UTCTime

Minute floor for the tick being attempted

-> m Bool 

Claim a minute floor for a schedule. True when the caller proceeds with the insert. False when another pool fired this minute.

tryAcquireCronLeader :: MonadArbiter m => SchemaName -> Text -> Text -> m BoolSource #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> Text

Queue name

-> Text

Schedule name

-> m Bool 

Try to acquire the (schema, queue, name) cron leader lock. Must be inside a transaction.

requestCronRun :: MonadArbiter m => SchemaName -> Text -> m RunRequestOutcomeSource #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> Text

Schedule name

-> m RunRequestOutcome 

Stamp a manual run request on an enabled schedule and NOTIFY the run-now channel. A pending, unexpired request is left as it stands.

claimCronRun :: MonadArbiter m => SchemaName -> Text -> m (Maybe CronScheduleRow)Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> Text

Schedule name

-> m (Maybe CronScheduleRow) 

Claim a pending run request, returning the claimed row. Nothing when no enabled schedule of that name has a pending request.

touchCronManualRun :: MonadArbiter m => SchemaName -> Text -> UTCTime -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> Text

Schedule name

-> UTCTime

When the manual run fired

-> m Int64 

Record when a manual run last fired a job for a cron schedule.

pendingCronRuns :: MonadArbiter m => SchemaName -> [Text] -> m [Text]Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> [Text]

Schedule names

-> m [Text] 

Enabled schedules among names that have a pending run request.

Worker registry operations

registerWorker :: MonadArbiter m => SchemaName -> UUID -> Text -> Maybe Text -> Maybe Int32 -> NominalDiffTime -> Maybe Value -> m (Maybe Bool)Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> UUID

Worker id

-> Text

Queue name

-> Maybe Text

Host name

-> Maybe Int32

Worker thread count

-> NominalDiffTime

Heartbeat age after which the worker counts as stale

-> Maybe Value

Free-form metadata

-> m (Maybe Bool) 

Register or refresh a worker and return its effective pause state (worker or queue). Nothing when the upsert returns no row.

heartbeatWorker :: MonadArbiter m => SchemaName -> UUID -> m (Maybe Bool)Source #

Record a heartbeat and return the worker's effective pause state (worker or queue). Nothing when the worker has no registry row.

setWorkerPaused :: MonadArbiter m => SchemaName -> UUID -> Bool -> m Int64Source #

Set a worker's pause flag and notify the worker.

markWorkerShuttingDown :: MonadArbiter m => SchemaName -> UUID -> m Int64Source #

Mark a worker as gracefully draining.

deregisterWorker :: MonadArbiter m => SchemaName -> UUID -> m Int64Source #

Remove a worker registry row.

workerRegistered :: MonadArbiter m => SchemaName -> UUID -> m BoolSource #

Whether the worker registry holds this identity.

listWorkers :: MonadArbiter m => SchemaName -> Maybe Text -> Maybe NominalDiffTime -> m [WorkerRow]Source #

List workers, optionally filtered by queue and heartbeat age.

sweepStaleWorkers :: MonadArbiter m => SchemaName -> m Int64Source #

Delete workers whose last heartbeat is older than their stale threshold.

Queue operations

ensureQueue :: MonadArbiter m => SchemaName -> Text -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> Text

Queue name

-> m Int64 

Insert an arbiter_queues row with defaults when absent.

setQueuePaused :: MonadArbiter m => SchemaName -> Text -> Bool -> m Int64Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> Text

Queue name

-> Bool 
-> m Int64 

Set the queue's paused flag, creating the row if missing, and notify its workers.

setQueueDLQRetention :: MonadArbiter m => SchemaName -> Text -> Maybe NominalDiffTime -> m ()Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> Text

Queue name

-> Maybe NominalDiffTime 
-> m () 

Set the age in seconds at which the reaper purges the queue's DLQ jobs, creating the row if missing. Nothing keeps them. A retention that rounds up to zero or below fails the column's check constraint.

getQueue :: MonadArbiter m => SchemaName -> Text -> m (Maybe QueueRow)Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> Text

Queue name

-> m (Maybe QueueRow) 

Get the arbiter_queues row for a single queue. Nothing when absent.

listQueues :: MonadArbiter m => SchemaName -> m [QueueRow]Source #

List all arbiter_queues rows, ordered by queue name.

schemaQueues :: MonadArbiter m => SchemaName -> [TableName] -> m [TableName]Source #

The given queues and every queue migrated into the schema whose tables exist, in name order. Maintenance covers this set, whatever registry the caller holds.

Global gate operations

runGated :: MonadArbiter m => SchemaName -> Text -> NominalDiffTime -> m a -> m (Maybe a)Source #

Arguments

:: MonadArbiter m 
=> SchemaName 
-> Text

Task identifier (used as the gate row key).

-> NominalDiffTime

Minimum interval between runs, in seconds.

-> m a

Work to perform when this caller wins the gate.

-> m (Maybe a) 

Run work at most once per interval across the schema's pools, keyed by task. Claims the watermark row in arbiter_gates with SELECT FOR UPDATE SKIP LOCKED. Nothing when the gate ran too recently or another pool holds the task.

runGatedBounded :: MonadArbiter m => SchemaName -> Text -> NominalDiffTime -> NominalDiffTime -> m a -> m (Maybe a)Source #

runGated with each statement of work bounded by limit. The bound is transaction-local.

runGatedShared :: (FromJSON a, MonadArbiter m, ToJSON a) => SchemaName -> Text -> NominalDiffTime -> NominalDiffTime -> m a -> m (Maybe (Shared a))Source #

Arguments

:: (FromJSON a, MonadArbiter m, ToJSON a) 
=> SchemaName 
-> Text 
-> NominalDiffTime

Minimum interval between runs.

-> NominalDiffTime

How long a published result stands.

-> m a 
-> m (Maybe (Shared a)) 

Run gated work, or read a result another caller published within maxAge of its claim. Nothing when there is no such result. The work runs after the gate transaction commits. The exclusion interval starts at publication. A failed run or publication restores the watermark. The restore is bounded by interval.

runGatedState :: (FromJSON s, MonadArbiter m, ToJSON s) => SchemaName -> Text -> NominalDiffTime -> (Maybe s -> m (a, s)) -> m (Maybe a)Source #

runGated where the task resumes from the state its last run left in the gate row, read under the claim and written with the watermark. A payload that no longer parses reads as no state.

runGatedStateBounded :: (FromJSON s, MonadArbiter m, ToJSON s) => SchemaName -> Text -> NominalDiffTime -> NominalDiffTime -> (Maybe s -> m (a, s)) -> m (Maybe a)Source #

runGatedState with each statement of work bounded by limit.

setLocalStatementTimeout :: MonadArbiter m => NominalDiffTime -> m ()Source #

Set a wall-clock limit for statements in the current transaction. The database aborts a statement that exceeds the limit.

micros :: NominalDiffTime -> IntSource #

An interval in microseconds, for the timeout and delay primitives.

gateNameFor :: MonadArbiter m => Text -> [Text] -> m TextSource #

A gate name for a list of parts. The sorted list, duplicates kept, while it fits the gate's key, an md5 digest of it beyond that.

data Shared aSource #

Where a shared result came from.

Constructors

Ran a

Result from work run by this caller.

Published Double a

Result read from the gate, with its age in seconds from the claim that produced it.

Unreadable Text

A published result this caller could not decode, with the parse error.

Instances

Instances details
Functor Shared Source # 
Instance details

Defined in Arbiter.Core.Operations.Gates

Methods

fmap :: (a -> b) -> Shared a -> Shared b#

(<$) :: a -> Shared b -> Shared a#

Eq a => Eq (Shared a) Source # 
Instance details

Defined in Arbiter.Core.Operations.Gates

Methods

(==) :: Shared a -> Shared a -> Bool#

(/=) :: Shared a -> Shared a -> Bool#

Show a => Show (Shared a) Source # 
Instance details

Defined in Arbiter.Core.Operations.Gates

Methods

showsPrec :: Int -> Shared a -> ShowS#

show :: Shared a -> String#

showList :: [Shared a] -> ShowS#