cachix-1.9.1: src/Cachix/Daemon/Types/TaskQueue.hs
module Cachix.Daemon.Types.TaskQueue
( TaskQueue (..),
Prioritized (..),
)
where
import Control.Concurrent.STM.TVar
import Data.Int (Int32)
import Data.PQueue.Max (MaxQueue)
import Protolude
-- | Internal wrapper that adds FIFO ordering within same-priority items
-- Items are ordered first by their task priority, then by insertion order (FIFO)
-- Uses circular sequence comparison to handle wraparound correctly
data Prioritized a = Prioritized
{ pTask :: !a,
pSequence :: !Int32
}
deriving stock (Eq)
instance (Ord a) => Ord (Prioritized a) where
compare p1 p2 =
case compare (pTask p1) (pTask p2) of
EQ -> compareSeq (pSequence p1) (pSequence p2)
other -> other
where
-- Circular sequence comparison: older (smaller) sequences come first
-- Uses signed arithmetic to handle wraparound (works for sequences up to 2^31 apart)
compareSeq s1 s2 =
let diff = s2 - s1
in compare diff 0
-- | A priority queue that maintains TBMQueue-compatible API
-- The queue is unbounded and prioritizes items by their Ord instance
-- Items with the same priority are returned in FIFO order
-- Sequence counter wraps around after 2^32 inserts
newtype TaskQueue a = TaskQueue (TVar (MaxQueue (Prioritized a), Int32, Bool))