arbiter-core-0.1.0.0
arbiter-core
Safe HaskellNone
LanguageGHC2024

Arbiter.Core

Description

Re-exports commonly used Arbiter functionality.

Synopsis

Core types

constructorKind :: (GKind (Rep a), Generic a) => a -> TextSource #

A value's constructor name, for a payload that wraps a sum. Requires Generic.

instance HasKind Envelope where
  kindOf = Just . constructorKind . envelopePayload
  kindsFor = constructorKinds @EmailPayload

constructorKinds :: GKind (Rep a) => [Text]Source #

Every constructor name of a type, in declaration order.

jobStatusFromText :: Text -> Either Text JobStatusSource #

Strict inverse of jobStatusToText. Unknown values are rejected.

jobStatusToText :: JobStatus -> TextSource #

The wire name for a status.

toTraceContext :: Maybe Text -> Maybe Text -> Maybe TraceContextSource #

A trace context from its two stored halves. An orphan tracestate is dropped.

andThen :: MonadUnliftIO m => m () -> m () -> m ()Source #

base's finally. The second action stays interruptible.

dayRetention :: Int32Source #

24h in seconds, a convenience value for setArchiveFor.

decodeStored :: FromJSON payload => Stored payload -> Either Text payloadSource #

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

defaultGroupedJob :: Text -> payload -> JobWrite payloadSource #

defaultJob with a group key. Jobs sharing a group key are processed serially.

defaultJob :: payload -> JobWrite payloadSource #

Ungrouped JobWrite with default values. For serial processing within a group, use defaultGroupedJob.

defaultMaxAttempts :: Int32Source #

Default attempt limit stamped onto jobs whose maxAttempts is unset.

defaultObservabilityHooks :: forall (m :: Type -> Type) payload. Applicative m => ObservabilityHooks m payloadSource #

No-op hooks. Override fields to add observability:

myHooks = defaultObservabilityHooks
  { onJobSuccess = \job startTime endTime -> do
      let duration = diffUTCTime endTime startTime
      logInfo $ "Job " <> show (primaryKey job) <> " took " <> show duration
  }

hoistObservabilityHooks :: (forall a. m a -> n a) -> ObservabilityHooks m payload -> ObservabilityHooks n payloadSource #

Hooks written in m, run in n through the given natural transformation. It must be a monad morphism, such as lift.

isRollup :: Job p Int64 q t adm -> BoolSource #

A rollup finalizer is any job whose parentState snapshot is present (an empty object from its insert or spawn, the merged child results before a DLQ move).

jobReadPairs :: ToJSON payload => JobRead payload -> [Pair]Source #

A job's JSON fields as key-value pairs.

jobReadSeries :: ToJSON payload => JobRead payload -> SeriesSource #

A job's JSON fields as an encoding series.

mapPayload :: (payload -> payload') -> Job payload key q insertedAt adm -> Job payload' key q insertedAt admSource #

Transform a job's payload without changing its stored metadata.

minMaxAttempts :: Int32Source #

Lowest attempt limit a job is stamped with. Every job gets at least one attempt.

setArchiveFor :: Maybe Int32 -> JobWrite payload -> JobWrite payloadSource #

Set the archive retention, in seconds.

setDedupKey :: Maybe DedupKey -> JobWrite payload -> JobWrite payloadSource #

Set the dedup key.

setGroupKey :: Maybe Text -> JobWrite payload -> JobWrite payloadSource #

Set the group key.

setMaxAttempts :: Maybe Int32 -> JobWrite payload -> JobWrite payloadSource #

Set the attempt limit. Nothing takes defaultMaxAttempts. Values below minMaxAttempts are raised to it.

setNotVisibleUntil :: Maybe UTCTime -> JobWrite payload -> JobWrite payloadSource #

Delay the job's first visibility.

setPayload :: payload' -> JobWrite payload -> JobWrite payload'Source #

Replace the payload.

setPriority :: Int32 -> JobWrite payload -> JobWrite payloadSource #

Set the claim priority. Lower numbers claim first. In a group, a retried job goes first.

setTraceContext :: Maybe TraceContext -> JobWrite payload -> JobWrite payloadSource #

Attach a trace context.

toStored :: ToJSON payload => payload -> Stored payloadSource #

A payload's stored form.

archiveFor :: Job payload key q insertedAt adm -> Maybe Int32Source #

Completed-job archive retention in seconds.

attempts :: Job payload Int64 q insertedAt adm -> Int32Source #

Number of attempts made so far.

claimSeq :: Job payload Int64 q insertedAt adm -> Int64Source #

The claim token.

claimedBy :: Job payload Int64 q insertedAt adm -> Maybe UUIDSource #

Holder of the outstanding claim. Nothing when no claim is outstanding.

dedupKey :: Job payload key q insertedAt adm -> Maybe DedupKeySource #

Deduplication strategy and key.

groupKey :: Job payload key q insertedAt adm -> Maybe TextSource #

Serial-processing group, or Nothing for an ungrouped job.

insertedAt :: Job payload key q insertedAt adm -> insertedAtSource #

Time at which the job was inserted.

lastAttemptedAt :: Job payload Int64 q insertedAt adm -> Maybe UTCTimeSource #

Time at which a worker last claimed the job.

lastError :: Job payload Int64 q insertedAt adm -> Maybe TextSource #

Error message from the last failed attempt.

maxAttempts :: Job payload key q insertedAt adm -> Maybe Int32Source #

Attempt limit before the job moves to the DLQ.

notVisibleUntil :: Job payload key q insertedAt adm -> Maybe UTCTimeSource #

Earliest time at which the job can be claimed.

parentId :: Job payload Int64 q insertedAt adm -> Maybe Int64Source #

Identifier of this job's parent in a job tree.

parentState :: Job payload Int64 q insertedAt adm -> Maybe ValueSource #

Snapshot of accumulated child results for a rollup finalizer.

payload :: Job payload key q insertedAt adm -> payloadSource #

User-defined payload stored as JSONB.

payloadKeys :: Job payload key q insertedAt adm -> admSource #

The labels and keys stamped from the payload at enqueue.

primaryKey :: Job payload key q insertedAt adm -> keySource #

Database-assigned identifier for a stored job.

priority :: Job payload key q insertedAt adm -> Int32Source #

Claim priority. Lower numbers have higher priority. In a group, a retried job goes first.

queueName :: Job payload key q insertedAt adm -> qSource #

Queue containing a stored job.

storedBytes :: Stored payload -> ByteStringSource #

The JSON bytes of a stored payload.

suspended :: Job payload Int64 q insertedAt adm -> BoolSource #

Whether the job is suspended. It stays unclaimable until resumed.

traceContext :: Job payload key q insertedAt adm -> Maybe TraceContextSource #

W3C trace context captured at enqueue.

updatedAt :: Job payload Int64 q insertedAt adm -> Maybe UTCTimeSource #

Time at which the job was last updated.

data DedupKeySource #

Deduplication strategy, checked on INSERT via ON CONFLICT on the dedup key.

Constructors

IgnoreDuplicate Text

Skip if the main queue table holds a job with this key (DO NOTHING). DLQ and archive rows do not conflict.

ReplaceDuplicate Text

Replace the main queue table's job with this key (DO UPDATE), unless it is in flight (claimed under a live lease), force-cancel-flagged, has a different parent, or has children. Children in the DLQ count.

Instances

Instances details
FromJSON DedupKey Source # 
Instance details

Defined in Arbiter.Core.Job.Dedup

ToJSON DedupKey Source # 
Instance details

Defined in Arbiter.Core.Job.Dedup

Eq DedupKey Source # 
Instance details

Defined in Arbiter.Core.Job.Dedup

Generic DedupKey Source # 
Instance details

Defined in Arbiter.Core.Job.Dedup

Associated Types

type Rep DedupKey 
Instance details

Defined in Arbiter.Core.Job.Dedup

type Rep DedupKey = D1 ('MetaData "DedupKey" "Arbiter.Core.Job.Dedup" "arbiter-core-0.1.0.0-inplace" 'False) (C1 ('MetaCons "IgnoreDuplicate" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text)) :+: C1 ('MetaCons "ReplaceDuplicate" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text)))
Show DedupKey Source # 
Instance details

Defined in Arbiter.Core.Job.Dedup

type Rep DedupKey Source # 
Instance details

Defined in Arbiter.Core.Job.Dedup

type Rep DedupKey = D1 ('MetaData "DedupKey" "Arbiter.Core.Job.Dedup" "arbiter-core-0.1.0.0-inplace" 'False) (C1 ('MetaCons "IgnoreDuplicate" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text)) :+: C1 ('MetaCons "ReplaceDuplicate" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text)))

class HasKind payload whereSource #

A payload's per-job variant label. With no instance, the job is unlabelled. An empty instance on a Generic payload labels it with the constructor name.

Minimal complete definition

Nothing

Methods

kindOf :: payload -> Maybe TextSource #

The label stored for a job.

default kindOf :: (GKind (Rep payload), Generic payload) => payload -> Maybe TextSource #

kindsFor :: [Text]Source #

Every label kindOf can return. Empty when the set is not known.

default kindsFor :: GKind (Rep payload) => [Text]Source #

Instances

Instances details
HasKind payload Source # 
Instance details

Defined in Arbiter.Core.Job.Kind

Methods

kindOf :: payload -> Maybe TextSource #

kindsFor :: [Text]Source #

data JobStatusSource #

Effective job status. Arbiter derives status from the stored fields. The status SQL in Arbiter.Core.Sql.Jobs is its source of truth.

Constructors

Ready

Visible, with attempts left. It can still wait behind its group head or a full concurrency or rate-limit key.

InFlight

Claimed by a worker, with the lease still running.

Backoff

Unclaimed with an attempt used, waiting out a delay. A nacked retry is here.

Scheduled

No attempt used, delayed to a future time. A nacked first attempt is here.

Suspended

Not claimable until resumed, such as a rollup finalizer with children.

Throttled

Held by a rate limit until tokens refill.

Cancelled

Force-cancel-flagged, waiting for teardown.

Exhausted

Visible but out of attempts, waiting for the reaper's DLQ sweep.

Instances

Instances details
FromJSON JobStatus Source # 
Instance details

Defined in Arbiter.Core.Job.Status

ToJSON JobStatus Source # 
Instance details

Defined in Arbiter.Core.Job.Status

Eq JobStatus Source # 
Instance details

Defined in Arbiter.Core.Job.Status

Bounded JobStatus Source # 
Instance details

Defined in Arbiter.Core.Job.Status

Enum JobStatus Source # 
Instance details

Defined in Arbiter.Core.Job.Status

Generic JobStatus Source # 
Instance details

Defined in Arbiter.Core.Job.Status

Associated Types

type Rep JobStatus 
Instance details

Defined in Arbiter.Core.Job.Status

type Rep JobStatus = D1 ('MetaData "JobStatus" "Arbiter.Core.Job.Status" "arbiter-core-0.1.0.0-inplace" 'False) (((C1 ('MetaCons "Ready" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "InFlight" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "Backoff" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Scheduled" 'PrefixI 'False) (U1 :: Type -> Type))) :+: ((C1 ('MetaCons "Suspended" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Throttled" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "Cancelled" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Exhausted" 'PrefixI 'False) (U1 :: Type -> Type))))
Show JobStatus Source # 
Instance details

Defined in Arbiter.Core.Job.Status

type Rep JobStatus Source # 
Instance details

Defined in Arbiter.Core.Job.Status

type Rep JobStatus = D1 ('MetaData "JobStatus" "Arbiter.Core.Job.Status" "arbiter-core-0.1.0.0-inplace" 'False) (((C1 ('MetaCons "Ready" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "InFlight" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "Backoff" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Scheduled" 'PrefixI 'False) (U1 :: Type -> Type))) :+: ((C1 ('MetaCons "Suspended" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Throttled" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "Cancelled" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Exhausted" 'PrefixI 'False) (U1 :: Type -> Type))))

data TraceContextSource #

A job's W3C trace context.

Constructors

TraceContext 

Fields

Instances

Instances details
Eq TraceContext Source # 
Instance details

Defined in Arbiter.Core.Job.TraceContext

Generic TraceContext Source # 
Instance details

Defined in Arbiter.Core.Job.TraceContext

Associated Types

type Rep TraceContext 
Instance details

Defined in Arbiter.Core.Job.TraceContext

type Rep TraceContext = D1 ('MetaData "TraceContext" "Arbiter.Core.Job.TraceContext" "arbiter-core-0.1.0.0-inplace" 'False) (C1 ('MetaCons "TraceContext" 'PrefixI 'True) (S1 ('MetaSel ('Just "traceparent") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text) :*: S1 ('MetaSel ('Just "tracestate") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe Text))))
Show TraceContext Source # 
Instance details

Defined in Arbiter.Core.Job.TraceContext

type Rep TraceContext Source # 
Instance details

Defined in Arbiter.Core.Job.TraceContext

type Rep TraceContext = D1 ('MetaData "TraceContext" "Arbiter.Core.Job.TraceContext" "arbiter-core-0.1.0.0-inplace" 'False) (C1 ('MetaCons "TraceContext" 'PrefixI 'True) (S1 ('MetaSel ('Just "traceparent") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text) :*: S1 ('MetaSel ('Just "tracestate") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe Text))))

type BackoffDelay = NominalDiffTimeSource #

How long to wait before the next attempt.

type ClaimSeq = Int64Source #

The token identifying one claim of a job.

type ClaimTime = UTCTimeSource #

When the worker thread received the job's batch.

type CurrentTime = UTCTimeSource #

The worker's clock reading after the extend landed.

type EndTime = UTCTimeSource #

For a success, when the ack committed. For a failure, when the handler failed the job.

type ErrorMsg = TextSource #

A failure message.

type JobId = Int64Source #

A job's primary key.

type JobPayload payload = (FromJSON payload, ToJSON payload, HasKind payload, HasRateLimit payload, HasConcurrency payload)Source #

The full payload contract. JSON round-trip for JSONB storage plus the kind, rate-limit and concurrency declarations. All three default to none.

type JobRead payload = Job payload Int64 Text UTCTime PayloadKeysSource #

A job read from the database.

type JobWrite payload = Job payload () () () ()Source #

A job ready to enqueue. Arbiter owns claim, retry, parent, rollup, and suspension state. Use the exported setters to configure enqueue fields.

data ObservabilityHooks (m :: Type -> Type) payloadSource #

Callbacks fired at each point of a job's lifecycle, for metrics, logging or tracing. The worker catches an exception thrown inside one and logs it at Warning.

Constructors

ObservabilityHooks 

Fields

Instances

Instances details
MonadUnliftIO m => Monoid (ObservabilityHooks m payload) Source # 
Instance details

Defined in Arbiter.Core.Job.Types

Methods

mempty :: ObservabilityHooks m payload#

mappend :: ObservabilityHooks m payload -> ObservabilityHooks m payload -> ObservabilityHooks m payload#

mconcat :: [ObservabilityHooks m payload] -> ObservabilityHooks m payload#

MonadUnliftIO m => Semigroup (ObservabilityHooks m payload) Source #

Run both hooks at each lifecycle point, left before right. The right one runs however the left ended. When both throw, the right's failure propagates.

Instance details

Defined in Arbiter.Core.Job.Types

Methods

(<>) :: ObservabilityHooks m payload -> ObservabilityHooks m payload -> ObservabilityHooks m payload#

sconcat :: NonEmpty (ObservabilityHooks m payload) -> ObservabilityHooks m payload#

stimes :: Integral b => b -> ObservabilityHooks m payload -> ObservabilityHooks m payload#

data PayloadKeysSource #

The labels and keys a stored job carries from its payload, one field each.

Constructors

PayloadKeys 

Fields

Instances

Instances details
Eq PayloadKeys Source # 
Instance details

Defined in Arbiter.Core.Job.Types

Generic PayloadKeys Source # 
Instance details

Defined in Arbiter.Core.Job.Types

Associated Types

type Rep PayloadKeys 
Instance details

Defined in Arbiter.Core.Job.Types

type Rep PayloadKeys = D1 ('MetaData "PayloadKeys" "Arbiter.Core.Job.Types" "arbiter-core-0.1.0.0-inplace" 'False) (C1 ('MetaCons "PayloadKeys" 'PrefixI 'True) (S1 ('MetaSel ('Just "jobKind") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe Text)) :*: (S1 ('MetaSel ('Just "jobRateLimitKey") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe RateLimitKey)) :*: S1 ('MetaSel ('Just "jobConcurrencyKey") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe ConcurrencyKey)))))
Show PayloadKeys Source # 
Instance details

Defined in Arbiter.Core.Job.Types

FromJSON payload => FromJSON (JobRead payload) Source #

Decode the complete persisted representation of a job.

Instance details

Defined in Arbiter.Core.Job.Types

Methods

parseJSON :: Value -> Parser (JobRead payload)#

parseJSONList :: Value -> Parser [JobRead payload]#

omittedField :: Maybe (JobRead payload)#

ToJSON payload => ToJSON (JobRead payload) Source # 
Instance details

Defined in Arbiter.Core.Job.Types

Methods

toJSON :: JobRead payload -> Value#

toEncoding :: JobRead payload -> Encoding#

toJSONList :: [JobRead payload] -> Value#

toEncodingList :: [JobRead payload] -> Encoding#

omitField :: JobRead payload -> Bool#

type Rep PayloadKeys Source # 
Instance details

Defined in Arbiter.Core.Job.Types

type Rep PayloadKeys = D1 ('MetaData "PayloadKeys" "Arbiter.Core.Job.Types" "arbiter-core-0.1.0.0-inplace" 'False) (C1 ('MetaCons "PayloadKeys" 'PrefixI 'True) (S1 ('MetaSel ('Just "jobKind") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe Text)) :*: (S1 ('MetaSel ('Just "jobRateLimitKey") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe RateLimitKey)) :*: S1 ('MetaSel ('Just "jobConcurrencyKey") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe ConcurrencyKey)))))

type RegistryAdmissionPolicies (registry :: JobPayloadRegistry) = (RegistryConcurrencyPolicies registry, RegistryRateLimitPolicies registry)Source #

The constraint that lets the migration collect a registry's declared policies of both kinds.

type StartTime = UTCTimeSource #

When the worker thread received the job's batch.

type Job payload key q insertedAt adm = JobRecord payload key q insertedAt admSource #

A job parametrized over payload, primary key, queue name, insertion timestamp, and the columns derived from the payload. The constructor is internal.

data Stored payloadSource #

A payload as the JSON bytes the database holds. The type it decodes to is a phantom.

Instances

Instances details
FromJSON (Stored payload) Source # 
Instance details

Defined in Arbiter.Core.Job.Types.Internal

Methods

parseJSON :: Value -> Parser (Stored payload)#

parseJSONList :: Value -> Parser [Stored payload]#

omittedField :: Maybe (Stored payload)#

ToJSON (Stored payload) Source #

The bytes are emitted as they are. toJSON has to parse them back.

Instance details

Defined in Arbiter.Core.Job.Types.Internal

Methods

toJSON :: Stored payload -> Value#

toEncoding :: Stored payload -> Encoding#

toJSONList :: [Stored payload] -> Value#

toEncodingList :: [Stored payload] -> Encoding#

omitField :: Stored payload -> Bool#

Eq (Stored payload) Source # 
Instance details

Defined in Arbiter.Core.Job.Types.Internal

Methods

(==) :: Stored payload -> Stored payload -> Bool#

(/=) :: Stored payload -> Stored payload -> Bool#

Show (Stored payload) Source # 
Instance details

Defined in Arbiter.Core.Job.Types.Internal

Methods

showsPrec :: Int -> Stored payload -> ShowS#

show :: Stored payload -> String#

showList :: [Stored payload] -> ShowS#

queryAny :: MonadArbiter m => Query Bool -> m BoolSource #

Run a boolean Query. The result is true when a row is true.

queryMaybe :: MonadArbiter m => Query a -> m (Maybe a)Source #

Run a Query and keep its first row.

type family Handler (m :: Type -> Type) job resultSource #

Backend-specific handler shape (for example Connection -> job -> m result). JobHandler instantiates it at one queue's job and result types.

type HasRegistry (m :: Type -> Type) (registry :: JobPayloadRegistry) = (MonadArbiter m, RegistryOf m ~ registry)Source #

MonadArbiter with the registry named, for signatures that mention it.

type JobHandler (m :: Type -> Type) payload result = Handler m (JobRead payload) resultSource #

A handler for payload's queue. result is what its registry entry declares.

class MonadUnliftIO m => MonadArbiter (m :: Type -> Type) whereSource #

Database abstraction for job queue operations. Each backend (postgresql-simple, hasql, Orville) provides an instance that maps queries to its native driver.

The instance also names the monad's schema and queue registry. The high-level API resolves table names and result types from them at compile time.

Associated Types

type RegistryOf (m :: Type -> Type) :: JobPayloadRegistrySource #

This monad's registry. The default reports an instance that omits it.

type RegistryOf (m :: Type -> Type) = TypeError ((('Text "No registry declared for " ':<>: 'ShowType m) ':$$: 'Text "Its MonadArbiter instance is missing the RegistryOf definition.") ':$$: (('Text "Add to the instance: type RegistryOf " ':<>: 'ShowType m) ':<>: 'Text " = YourRegistry")) :: JobPayloadRegistry

type Handler (m :: Type -> Type) job resultSource #

Backend-specific handler shape (for example Connection -> job -> m result). JobHandler instantiates it at one queue's job and result types.

Methods

getSchema :: m SchemaNameSource #

The schema name for this monad's arbiter tables.

executeQuery :: Query a -> m [a]Source #

Run a query and decode the result rows. The text, its parameters, and the decoder travel together in the Query.

executeQueryPrepared :: Query a -> m [a]Source #

executeQuery for a hot statement whose text is stable across calls. A backend may prepare it once per connection.

executeStatement :: Query a -> m Int64Source #

Run a statement, returning the number of affected rows. The Query decoder is ignored.

withDbTransaction :: m a -> m aSource #

Run an action in a transaction. Nesting creates savepoints.

runHandlerWithConnection :: JobHandler m payload (ResultOf m payload) -> JobRead payload -> m (ResultOf m payload)Source #

Run a job handler in the backend's handler shape.

getListener :: m (Maybe Listener)Source #

The env's shared LISTEN/NOTIFY listener, or Nothing for poll-only.

type family RegistryOf (m :: Type -> Type) :: JobPayloadRegistrySource #

This monad's registry. The default reports an instance that omits it.

type ResultOf (m :: Type -> Type) payload = ResultFor payload (RegistryOf m)Source #

The result type declared by payload's registry entry. It is not injective. A signature naming it needs another argument to determine payload.

High-level operations

The admin row records share field names with each other and with Job. Unqualified use needs DuplicateRecordFields or OverloadedRecordDot.

Job tree DSL

(<~~) :: JobWrite payload -> NonEmpty (JobWrite payload) -> JobTree payload infixr 6Source #

Infix rollup for leaf-only children.

defaultJob reducer <~~ (defaultJob mapper1 :| [defaultJob mapper2])

leaf :: JobWrite payload -> JobTree payloadSource #

A single job with no children.

rollup :: JobWrite payload -> NonEmpty (JobTree payload) -> JobTree payloadSource #

A finalizer running once no child of it is left in the main queue. Nested rollups do not merge on their own. An intermediate finalizer returns the merged value for results to travel upward.

rollup (defaultJob root)
  ( leaf (defaultJob leaf1)
  :| [leaf (defaultJob leaf2)]
  )

data JobTree payloadSource #

A tree of jobs. Leaves are single jobs. Finalizers are parents with children that run immediately while the parent waits for completion.

Job results

Archived jobs

data ArchiveJob payloadSource #

A completed job in the archive.

Constructors

ArchiveJob 

Fields

Instances

Instances details
FromJSON payload => FromJSON (ArchiveJob payload) Source # 
Instance details

Defined in Arbiter.Core.Job.Archive

ToJSON payload => ToJSON (ArchiveJob payload) Source # 
Instance details

Defined in Arbiter.Core.Job.Archive

Methods

toJSON :: ArchiveJob payload -> Value#

toEncoding :: ArchiveJob payload -> Encoding#

toJSONList :: [ArchiveJob payload] -> Value#

toEncodingList :: [ArchiveJob payload] -> Encoding#

omitField :: ArchiveJob payload -> Bool#

Eq payload => Eq (ArchiveJob payload) Source # 
Instance details

Defined in Arbiter.Core.Job.Archive

Methods

(==) :: ArchiveJob payload -> ArchiveJob payload -> Bool#

(/=) :: ArchiveJob payload -> ArchiveJob payload -> Bool#

Generic (ArchiveJob payload) Source # 
Instance details

Defined in Arbiter.Core.Job.Archive

Associated Types

type Rep (ArchiveJob payload) 
Instance details

Defined in Arbiter.Core.Job.Archive

type Rep (ArchiveJob payload) = D1 ('MetaData "ArchiveJob" "Arbiter.Core.Job.Archive" "arbiter-core-0.1.0.0-inplace" 'False) (C1 ('MetaCons "ArchiveJob" 'PrefixI 'True) ((S1 ('MetaSel ('Just "archivePrimaryKey") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64) :*: S1 ('MetaSel ('Just "completedAt") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 UTCTime)) :*: (S1 ('MetaSel ('Just "jobSnapshot") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (JobSnapshot payload)) :*: S1 ('MetaSel ('Just "archivedResult") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe Value)))))

Methods

from :: ArchiveJob payload -> Rep (ArchiveJob payload) x#

to :: Rep (ArchiveJob payload) x -> ArchiveJob payload#

Show payload => Show (ArchiveJob payload) Source # 
Instance details

Defined in Arbiter.Core.Job.Archive

Methods

showsPrec :: Int -> ArchiveJob payload -> ShowS#

show :: ArchiveJob payload -> String#

showList :: [ArchiveJob payload] -> ShowS#

type Rep (ArchiveJob payload) Source # 
Instance details

Defined in Arbiter.Core.Job.Archive

type Rep (ArchiveJob payload) = D1 ('MetaData "ArchiveJob" "Arbiter.Core.Job.Archive" "arbiter-core-0.1.0.0-inplace" 'False) (C1 ('MetaCons "ArchiveJob" 'PrefixI 'True) ((S1 ('MetaSel ('Just "archivePrimaryKey") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int64) :*: S1 ('MetaSel ('Just "completedAt") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 UTCTime)) :*: (S1 ('MetaSel ('Just "jobSnapshot") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (JobSnapshot payload)) :*: S1 ('MetaSel ('Just "archivedResult") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe Value)))))

Schema names

type SchemaName = TextSource #

PostgreSQL schema name, e.g. "arbiter".

type TableName = TextSource #

Unqualified table name within a schema, e.g. "email_jobs".

Exceptions

orThrowInternal :: MonadIO m => (e -> Text) -> Either e a -> m aSource #

The Right value, or throwInternal on the rendered Left.

orThrowParsing :: MonadIO m => Either Text a -> m aSource #

The Right value, or throwParsing on the Left message.

throwBranchCancel :: MonadIO m => Text -> m aSource #

Cancel the parent and every descendant. A job with no parent cancels only itself and its descendants.

throwNack :: MonadIO m => m aSource #

Return the job to the queue without consuming an attempt.

throwNackAfter :: MonadIO m => NominalDiffTime -> m aSource #

Return the job to the queue without consuming an attempt, visible again after a delay in seconds.

throwPermanent :: MonadIO m => Text -> m aSource #

Fail the job straight to the DLQ.

throwRetryable :: MonadIO m => Text -> m aSource #

Fail the job and let it retry.

throwRetryableAfter :: MonadIO m => NominalDiffTime -> Text -> m aSource #

Fail the job and retry it after a delay in seconds, in place of the pool's backoff. The failure uses an attempt.

throwTreeCancel :: MonadIO m => Text -> m aSource #

Cancel the whole job tree.

newtype BranchCancelExceptionSource #

Cancel the parent and every descendant. A job with no parent cancels only itself and its descendants. A grandparent above is resumed.

Instances

Instances details
Eq BranchCancelException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Exception BranchCancelException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Generic BranchCancelException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Associated Types

type Rep BranchCancelException 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep BranchCancelException = D1 ('MetaData "BranchCancelException" "Arbiter.Core.Exceptions" "arbiter-core-0.1.0.0-inplace" 'True) (C1 ('MetaCons "BranchCancelException" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text)))
Show BranchCancelException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep BranchCancelException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep BranchCancelException = D1 ('MetaData "BranchCancelException" "Arbiter.Core.Exceptions" "arbiter-core-0.1.0.0-inplace" 'True) (C1 ('MetaCons "BranchCancelException" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text)))

newtype InternalExceptionSource #

Generic engine-internal failure, such as a missing connection or bad parameters.

Constructors

InternalException Text 

Instances

Instances details
Eq InternalException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Exception InternalException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Generic InternalException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Associated Types

type Rep InternalException 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep InternalException = D1 ('MetaData "InternalException" "Arbiter.Core.Exceptions" "arbiter-core-0.1.0.0-inplace" 'True) (C1 ('MetaCons "InternalException" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text)))
Show InternalException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep InternalException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep InternalException = D1 ('MetaData "InternalException" "Arbiter.Core.Exceptions" "arbiter-core-0.1.0.0-inplace" 'True) (C1 ('MetaCons "InternalException" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text)))

newtype JobDeadlineExceededSource #

A batch's claim hooks and handler ran past the pool's maximum job duration. Classified as a retryable failure.

Instances

Instances details
Eq JobDeadlineExceeded Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Exception JobDeadlineExceeded Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Generic JobDeadlineExceeded Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Associated Types

type Rep JobDeadlineExceeded 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep JobDeadlineExceeded = D1 ('MetaData "JobDeadlineExceeded" "Arbiter.Core.Exceptions" "arbiter-core-0.1.0.0-inplace" 'True) (C1 ('MetaCons "JobDeadlineExceeded" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text)))
Show JobDeadlineExceeded Source # 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep JobDeadlineExceeded Source # 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep JobDeadlineExceeded = D1 ('MetaData "JobDeadlineExceeded" "Arbiter.Core.Exceptions" "arbiter-core-0.1.0.0-inplace" 'True) (C1 ('MetaCons "JobDeadlineExceeded" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text)))

data JobExceptionSource #

Decisions a handler can signal by throwing. The worker catches it and retries, dead-letters or cancels the job.

Constructors

Retryable JobRetryableException

Retries the job after its delay, or with backoff.

Permanent JobPermanentException

Moves the job to the DLQ.

TreeCancel TreeCancelException

Deletes the entire job tree from root to leaves.

BranchCancel BranchCancelException

Cancels the parent and every descendant. A job with no parent cancels only itself and its descendants.

data JobForceCancelledSource #

Async exception for an operator force-cancel. Names the cancelled jobs, then the jobs the same check found reclaimed or gone.

Constructors

JobForceCancelled [Int64] [Int64] 

data JobGoneExceptionSource #

Job was deleted or reclaimed between claim and ack. The worker recognizes this signal and skips retry/DLQ. The message is the reason reported to onJobUnavailable. The ids are the jobs that are gone. Empty when the thrower did not name them.

Constructors

JobGoneException Text [Int64] 

Instances

Instances details
Eq JobGoneException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Exception JobGoneException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Generic JobGoneException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Associated Types

type Rep JobGoneException 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep JobGoneException = D1 ('MetaData "JobGoneException" "Arbiter.Core.Exceptions" "arbiter-core-0.1.0.0-inplace" 'False) (C1 ('MetaCons "JobGoneException" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [Int64])))
Show JobGoneException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep JobGoneException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep JobGoneException = D1 ('MetaData "JobGoneException" "Arbiter.Core.Exceptions" "arbiter-core-0.1.0.0-inplace" 'False) (C1 ('MetaCons "JobGoneException" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [Int64])))

newtype JobNackExceptionSource #

Reprocess the job later without recording a failure (a soft nack). The worker skips retry/DLQ, hands back the attempt the claim consumed, and leaves the job to become visible again after the delay in seconds, or when its lease lapses when there is none.

Instances

Instances details
Eq JobNackException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Exception JobNackException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Generic JobNackException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Associated Types

type Rep JobNackException 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep JobNackException = D1 ('MetaData "JobNackException" "Arbiter.Core.Exceptions" "arbiter-core-0.1.0.0-inplace" 'True) (C1 ('MetaCons "JobNackException" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe NominalDiffTime))))
Show JobNackException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep JobNackException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep JobNackException = D1 ('MetaData "JobNackException" "Arbiter.Core.Exceptions" "arbiter-core-0.1.0.0-inplace" 'True) (C1 ('MetaCons "JobNackException" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe NominalDiffTime))))

newtype JobPermanentExceptionSource #

Permanent failure. The job goes straight to the DLQ.

Instances

Instances details
Eq JobPermanentException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Exception JobPermanentException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Generic JobPermanentException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Associated Types

type Rep JobPermanentException 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep JobPermanentException = D1 ('MetaData "JobPermanentException" "Arbiter.Core.Exceptions" "arbiter-core-0.1.0.0-inplace" 'True) (C1 ('MetaCons "JobPermanentException" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text)))
Show JobPermanentException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep JobPermanentException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep JobPermanentException = D1 ('MetaData "JobPermanentException" "Arbiter.Core.Exceptions" "arbiter-core-0.1.0.0-inplace" 'True) (C1 ('MetaCons "JobPermanentException" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text)))

data JobRetryableExceptionSource #

Transient failure. The job is retried after the delay in seconds, or with the pool's backoff when there is none.

Instances

Instances details
Eq JobRetryableException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Exception JobRetryableException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Generic JobRetryableException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Associated Types

type Rep JobRetryableException 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep JobRetryableException = D1 ('MetaData "JobRetryableException" "Arbiter.Core.Exceptions" "arbiter-core-0.1.0.0-inplace" 'False) (C1 ('MetaCons "JobRetryableException" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe NominalDiffTime))))
Show JobRetryableException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep JobRetryableException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep JobRetryableException = D1 ('MetaData "JobRetryableException" "Arbiter.Core.Exceptions" "arbiter-core-0.1.0.0-inplace" 'False) (C1 ('MetaCons "JobRetryableException" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe NominalDiffTime))))

newtype ParsingExceptionSource #

Row decoding failure (engine-internal). Classified as a permanent failure by the worker.

Constructors

ParsingException Text 

Instances

Instances details
Eq ParsingException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Exception ParsingException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Generic ParsingException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Associated Types

type Rep ParsingException 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep ParsingException = D1 ('MetaData "ParsingException" "Arbiter.Core.Exceptions" "arbiter-core-0.1.0.0-inplace" 'True) (C1 ('MetaCons "ParsingException" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text)))
Show ParsingException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep ParsingException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep ParsingException = D1 ('MetaData "ParsingException" "Arbiter.Core.Exceptions" "arbiter-core-0.1.0.0-inplace" 'True) (C1 ('MetaCons "ParsingException" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text)))

newtype TreeCancelExceptionSource #

Cancel the whole job tree, root to leaves.

Instances

Instances details
Eq TreeCancelException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Exception TreeCancelException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Generic TreeCancelException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

Associated Types

type Rep TreeCancelException 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep TreeCancelException = D1 ('MetaData "TreeCancelException" "Arbiter.Core.Exceptions" "arbiter-core-0.1.0.0-inplace" 'True) (C1 ('MetaCons "TreeCancelException" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text)))
Show TreeCancelException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep TreeCancelException Source # 
Instance details

Defined in Arbiter.Core.Exceptions

type Rep TreeCancelException = D1 ('MetaData "TreeCancelException" "Arbiter.Core.Exceptions" "arbiter-core-0.1.0.0-inplace" 'True) (C1 ('MetaCons "TreeCancelException" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text)))

Cron schedule and worker health helpers

effectiveExpression :: CronScheduleRow -> TextSource #

The override expression if set, else the default.

effectiveOverlap :: CronScheduleRow -> TextSource #

The override overlap policy if set, else the default.

effectiveTimezone :: CronScheduleRow -> Maybe TextSource #

The override timezone if set, else the default. Nothing means UTC.

workerHealthFromText :: Text -> Either Text WorkerHealthSource #

Decode the health SQL token into a WorkerHealth.

workerHealthToText :: WorkerHealth -> TextSource #

The health SQL token of a WorkerHealth.

Connection pool settings

Listener

Notification collides with Database.PostgreSQL.Simple.Notification. Import it from Arbiter.Core.Listen.

data ListenerSource #

Handle to an environment's shared, refcounted LISTEN hub slot.

data ListenConnSource #

The connection operations the hub loop needs.

Constructors

ListenConn 

Fields

data HubLogSource #

Hub event reporting preferences for a registrant.

Constructors

HubLog 

Fields

withChannels :: MonadUnliftIO m => Listener -> HubLog -> [(ByteString, Notification -> m ())] -> (STM Bool -> m a) -> m aSource #

Register the caller's channels on the env's shared hub for the duration of the body. The STM action reports True while they are all subscribed. A reconnect resets it.

newListener :: ((ListenConn -> IO ()) -> IO ()) -> IO ListenerSource #

A Listener with a fresh hub slot over a connection runner.