packages feed

keiro-dsl-0.2.0.0: test/conformance-queue-runtime/Main.hs

{- | EP-5 runtime conformance: the scaffolded pgmq @QueuePolicy@ — the
@RetryPolicy@ and the @JobOutcome@ disposition — compiled against the LIVE
@Keiro.PGMQ.Job@ runtime. Running it pins the dangerous inversions over the
real JobOutcome: storeFailure ⇒ Retry (transient) and decodeFailure ⇒ Dead
(poison), plus the dlq=on ceiling.
-}
module Main (main) where

import Control.Monad (unless)
import Data.Text (Text)
import Generated.HospitalCapacity.Reservation_work.Queue (ReservationWorkItem (..), encodeReservationWorkItem, groupKeyFor, parseReservationWorkItem)
import Generated.HospitalCapacity.Reservation_work.QueuePolicy (jobOrdering, jobOutcomeFor, jobTuningFor, queueProvision, retryPolicy)
import Keiro.Dsl.Validate (derivedQueueTrio)
import Keiro.PGMQ.Codec (mkJobCodec)
import Keiro.PGMQ.Job (Job (..), JobOrdering (..), JobOutcome (..), JobTuning (..), RetryPolicy (..), defaultJobTuning, queueProvisionConfigs)
import Keiro.PGMQ.Runtime (QueueRef (..), queueRef)
import Pgmq.Config qualified as Config
import Pgmq.Types (queueNameToText)
import System.Exit (exitFailure)

isRetry :: JobOutcome -> Bool
isRetry (Retry _) = True
isRetry _ = False

isDead :: JobOutcome -> Bool
isDead (Dead _) = True
isDead _ = False

main :: IO ()
main = do
    let storeOk = isRetry (jobOutcomeFor "storeFailure") -- transient: MUST retry
        decodeOk = isDead (jobOutcomeFor "decodeFailure") -- poison: MUST dead-letter
        ceilingOk = maxRetries retryPolicy == 3 && useDeadLetter retryPolicy
        orderingOk = jobOrdering == FifoThroughput
        tuningOk = ordering (jobTuningFor defaultJobTuning) == FifoThroughput
        job =
            Job
                { jobName = "reservation-work"
                , jobQueue = queueRef "hospital_capacity.reservation_work"
                , jobCodec = mkJobCodec encodeReservationWorkItem parseReservationWorkItem
                , jobPolicy = retryPolicy
                }
        provisionOk = case queueProvisionConfigs queueProvision job of
            [mainQueue, deadLetterQueue] ->
                Config.fifoIndex mainQueue
                    && not (Config.fifoIndex deadLetterQueue)
                    && isStandard mainQueue
                    && isStandard deadLetterQueue
            _ -> False
        groupKeyOk = groupKeyFor (ReservationWorkItem "rsv-123" "hsp-1" "cmd-1" True) == "rsv-123"
        vectors =
            [ "hospital_capacity.reservation_work"
            , "Repro.Work"
            , "a__b..c"
            , "9lives"
            , "already_dlq"
            , "hospital_capacity.reservation_work.per_hospital_fifo_lane_assignments"
            ]
        parity = [(logical, derivedQueueTrio logical == liveQueueTrio logical) | logical <- vectors]
    putStrLn ("storeFailure => Retry (transient): " <> show storeOk)
    putStrLn ("decodeFailure => Dead (poison): " <> show decodeOk)
    putStrLn ("retry ceiling + dlq on: " <> show ceilingOk)
    putStrLn ("ordering lowered to FifoThroughput: " <> show orderingOk)
    putStrLn ("provision includes the FIFO index: " <> show provisionOk)
    putStrLn ("groupKeyFor projects the payload field: " <> show groupKeyOk)
    putStrLn ("jobTuningFor overlays deployment tuning: " <> show tuningOk)
    mapM_ (\(logical, matches) -> putStrLn ("derivedQueueTrio " <> show logical <> " == live queueRef: " <> show matches)) parity
    unless (storeOk && decodeOk && ceilingOk && orderingOk && provisionOk && groupKeyOk && tuningOk && all snd parity) exitFailure

liveQueueTrio :: Text -> (Text, Text, Text)
liveQueueTrio logical =
    ( physical
    , queueNameToText (dlqName ref)
    , "pgmq.q_" <> physical
    )
  where
    ref = queueRef logical
    physical = queueNameToText (physicalName ref)

isStandard :: Config.QueueConfig -> Bool
isStandard config = case Config.queueType config of
    Config.StandardQueue -> True
    _ -> False