packages feed

pgmq-effectful 0.6.0.0 → 0.6.1.0

raw patch · 3 files changed

+80/−34 lines, 3 filesdep +unixdep ~effectful-coredep ~ephemeral-pgPVP ok

version bump matches the API change (PVP)

Dependencies added: unix

Dependency ranges changed: effectful-core, ephemeral-pg

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -1,5 +1,21 @@ # Revision history for pgmq-effectful +## 0.6.1.0 -- 2026-09-16++Widen the `effectful-core` bound to `^>=2.6 || ^>=2.7`, adding support for 2.7 and dropping+the untested claim of support for 2.5. Nothing in the effect layer changed: the `Pgmq` effect,+both interpreters, and every exported name are identical, and both interpreters already+discarded the `LocalEnv` argument whose type lost a parameter in 2.7.++Prefer `effectful-core` 2.7.1.1 or newer over 2.7.0.0 — the `Pgmq` effect is dynamically+dispatched, and 2.7.0.0 carries an upstream per-operation overhead regression for dynamic+dispatch that 2.7.1.1 fixed.++The test suite now requires `ephemeral-pg >=0.3.1.0` and pins its temporary PostgreSQL+clusters to `/tmp/ephpg-pgmq-hs-<uid>`, so a run killed mid-test leaves a postmaster a later+run can reap. It therefore depends on `unix` to read the effective uid. No library+dependency changed.+ ## 0.6.0.0 -- 2026-09-10  Add grouped-head reads and polling to plain/traced interpreters, with Consumer/receive spans.
pgmq-effectful.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.4 name: pgmq-effectful-version: 0.6.0.0+version: 0.6.1.0 synopsis: Effectful effects for PGMQ (PostgreSQL Message Queue) description:   Effectful effects and interpreters for pgmq-hs, a Haskell client@@ -58,7 +58,7 @@     base >=4.18 && <5,     bytestring >=0.11 && <0.13,     case-insensitive >=1.2 && <1.3,-    effectful-core ^>=2.5 || ^>=2.6,+    effectful-core ^>=2.6 || ^>=2.7,     hasql ^>=1.10,     hasql-pool ^>=1.4,     hs-opentelemetry-api >=1.0 && <2,@@ -104,8 +104,8 @@     aeson >=2.0 && <2.3,     base >=4.18 && <5,     directory,-    effectful-core ^>=2.5 || ^>=2.6,-    ephemeral-pg >=0.2.1,+    effectful-core ^>=2.6 || ^>=2.7,+    ephemeral-pg >=0.3.1.0,     hasql ^>=1.10,     hasql-pool ^>=1.4,     hs-opentelemetry-api >=1.0 && <2,@@ -122,5 +122,6 @@     tasty ^>=1.5,     tasty-hunit ^>=0.10,     text >=2.0 && <2.2,+    unix,     unordered-containers >=0.2 && <0.3,     vector ^>=0.13,
test/EphemeralDb.hs view
@@ -15,6 +15,7 @@  import Control.Monad (filterM, when) import Data.List.NonEmpty (NonEmpty (..))+import Data.Monoid (Last (..)) import Data.Text.IO qualified as TextIO import Database.PostgreSQL.Migrate   ( defaultRunOptions,@@ -22,47 +23,75 @@     runMigrationPlan,   ) import EphemeralPg-  ( StartError,+  ( Config (temporaryRoot),+    StartError,     connectionSettings,-    withCached,+    defaultCacheConfig,+    defaultConfig,+    withCachedConfig,   ) import Hasql.Pool qualified as Pool import Hasql.Pool.Config qualified as PoolConfig import Hasql.Session qualified as Session import Pgmq.Migration qualified as Migration-import System.Directory (doesFileExist)+import System.Directory (createDirectoryIfMissing, doesFileExist) import System.Environment (lookupEnv)+import System.Posix.User (getEffectiveUserID) +-- | Root directory for ephemeral PostgreSQL clusters.+--+-- ephemeral-pg reaps abandoned clusters at startup, but only within its own+-- temporary root. With 'temporaryRoot' unset that root is @$TMPDIR@, which+-- @nix develop@ makes unique per shell, so a run never reclaims what an earlier+-- session abandoned. Pinning one root across sessions keeps them reachable.+--+-- The path is keyed by effective uid. It is a fixed location created @0700@, so+-- a run under a different user -- the Nix build sandbox -- must not collide with+-- a directory it cannot write to.+ephemeralRoot :: IO FilePath+ephemeralRoot = do+  uid <- getEffectiveUserID+  pure ("/tmp/ephpg-pgmq-hs-" <> show uid)++-- | Cached-startup configuration pinned to 'ephemeralRoot'.+ephemeralConfig :: IO Config+ephemeralConfig = do+  root <- ephemeralRoot+  createDirectoryIfMissing True root+  pure defaultConfig {temporaryRoot = Last (Just root)}+ -- | Run an action with a temporary PostgreSQL database that has the -- pgmq schema installed. withPgmqDb :: (Pool.Pool -> IO a) -> IO (Either StartError a)-withPgmqDb action = withCached $ \db -> do-  let connSettings = connectionSettings db-      poolConfig =-        PoolConfig.settings-          [ PoolConfig.size 3,-            PoolConfig.staticConnectionSettings connSettings-          ]-  pool <- Pool.acquire poolConfig-  version <- lookupEnv "PGMQ_TEST_SCHEMA_VERSION"-  case version of-    Just "1.12.0" -> do-      paths <- filterM doesFileExist ["test/fixtures/pgmq-1.12.0.sql", "pgmq-effectful/test/fixtures/pgmq-1.12.0.sql"]-      path <- case paths of-        candidate : _ -> pure candidate-        [] -> error "Missing packaged PGMQ 1.12.0 test fixture"-      sql <- TextIO.readFile path-      Pool.use pool (Session.script sql) >>= either (error . show) pure-    Nothing -> installNative connSettings-    Just "1.13.0" -> installNative connSettings-    Just invalid -> error ("Invalid PGMQ_TEST_SCHEMA_VERSION: " <> invalid)-  required <- (== Just "1") <$> lookupEnv "PGMQ_REQUIRE_PARTMAN"-  -- Required runs fail for absent or unusable pg_partman, not just missing metadata.-  partman <- Pool.use pool (Session.script "CREATE SCHEMA IF NOT EXISTS partman; CREATE EXTENSION IF NOT EXISTS pg_partman SCHEMA partman")-  case partman of-    Left err -> when required (error ("PGMQ_REQUIRE_PARTMAN=1: " <> show err))-    Right () -> pure ()-  action pool+withPgmqDb action =+  ephemeralConfig >>= \config ->+    withCachedConfig config defaultCacheConfig $ \db -> do+      let connSettings = connectionSettings db+          poolConfig =+            PoolConfig.settings+              [ PoolConfig.size 3,+                PoolConfig.staticConnectionSettings connSettings+              ]+      pool <- Pool.acquire poolConfig+      version <- lookupEnv "PGMQ_TEST_SCHEMA_VERSION"+      case version of+        Just "1.12.0" -> do+          paths <- filterM doesFileExist ["test/fixtures/pgmq-1.12.0.sql", "pgmq-effectful/test/fixtures/pgmq-1.12.0.sql"]+          path <- case paths of+            candidate : _ -> pure candidate+            [] -> error "Missing packaged PGMQ 1.12.0 test fixture"+          sql <- TextIO.readFile path+          Pool.use pool (Session.script sql) >>= either (error . show) pure+        Nothing -> installNative connSettings+        Just "1.13.0" -> installNative connSettings+        Just invalid -> error ("Invalid PGMQ_TEST_SCHEMA_VERSION: " <> invalid)+      required <- (== Just "1") <$> lookupEnv "PGMQ_REQUIRE_PARTMAN"+      -- Required runs fail for absent or unusable pg_partman, not just missing metadata.+      partman <- Pool.use pool (Session.script "CREATE SCHEMA IF NOT EXISTS partman; CREATE EXTENSION IF NOT EXISTS pg_partman SCHEMA partman")+      case partman of+        Left err -> when required (error ("PGMQ_REQUIRE_PARTMAN=1: " <> show err))+        Right () -> pure ()+      action pool   where     installNative connSettings = do       component <- either (error . ("Invalid PGMQ migration component: " <>) . show) pure Migration.pgmqMigrations