packages feed

shibuya-pgmq-adapter 0.12.0.0 → 0.13.0.0

raw patch · 5 files changed

+95/−10 lines, 5 filesdep ~pgmq-coredep ~pgmq-effectfuldep ~pgmq-hasqlPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: pgmq-core, pgmq-effectful, pgmq-hasql, pgmq-migration

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -1,5 +1,37 @@ # Changelog +## 0.13.0.0 — 2026-08-09++Driven by the `pgmq-hs` 0.5 release. The adapter remains paired with+`shibuya-core 0.8.0.1`, and its own public function and record signatures are unchanged.++### Breaking Changes++- Requires `pgmq-core ^>=0.5`, `pgmq-effectful ^>=0.5`, and `pgmq-hasql ^>=0.5` in+  the library, plus `pgmq-migration ^>=0.5` in the test stanza, up from the 0.4 family.+- The re-exported `parseQueueName` now accepts only non-empty names of at most 47+  lowercase ASCII letters, digits, or underscores (`[a-z0-9_]{1,47}`). Operators must+  detect and transactionally remediate mixed-case `pgmq.meta` rows before rollout; see+  [Installing the PGMQ schema](../docs/user/pgmq-getting-started.md#before-upgrading-to-pgmq--05).++### Reliability++- `mkLease` handles pgmq-hs 0.5's `Maybe Message` visibility-timeout result. When a+  message was deleted, archived, or popped before extension reached it, `leaseExtend`+  returns normally and leaves the last confirmed visibility deadline unchanged. A live+  row still advances that deadline from the value PostgreSQL returns.+- The existing bounded retry wrapper inherits pgmq-effectful 0.5's broader transient+  SQLSTATE classification: serialization failures, deadlocks, lock-unavailable errors,+  server shutdown/recovery, and class 53 resource errors are now eligible for retry.+- The test harness and downstream components inherit pgmq-migration 0.5's notification+  crash-safety migration, which fails open after crash recovery truncates the unlogged+  throttle table so insert notifications continue until reconciliation restores it.++### Tests++- Added a PostgreSQL-backed regression for extending a lease after its message is deleted+  and a public-boundary regression for lowercase, uppercase, and empty queue names.+ ## 0.12.0.0 — 2026-07-14  Driven by the `pgmq-hs` 0.4 release. Still paired with `shibuya-core 0.8.0.1`
shibuya-pgmq-adapter.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.12 name: shibuya-pgmq-adapter-version: 0.12.0.0+version: 0.13.0.0 synopsis: PGMQ adapter for the Shibuya queue processing framework description:   A Shibuya adapter that integrates with pgmq (PostgreSQL Message Queue)@@ -46,9 +46,9 @@     hasql ^>=1.10,     hasql-pool ^>=1.4,     hasql-transaction ^>=1.2,-    pgmq-core ^>=0.4,-    pgmq-effectful ^>=0.4,-    pgmq-hasql ^>=0.4,+    pgmq-core ^>=0.5,+    pgmq-effectful ^>=0.5,+    pgmq-hasql ^>=0.5,     shibuya-core ^>=0.8.0.1,     stm ^>=2.5,     streamly ^>=0.11,@@ -113,10 +113,10 @@     hasql-transaction ^>=1.2,     hspec ^>=2.11,     pg-migrate ^>=1.1,-    pgmq-core ^>=0.4,-    pgmq-effectful ^>=0.4,-    pgmq-hasql ^>=0.4,-    pgmq-migration ^>=0.4,+    pgmq-core ^>=0.5,+    pgmq-effectful ^>=0.5,+    pgmq-hasql ^>=0.5,+    pgmq-migration ^>=0.5,     quickcheck-instances ^>=0.3,     random,     shibuya-core ^>=0.8.0.1,
src/Shibuya/Adapter/Pgmq/Internal.hs view
@@ -202,7 +202,9 @@                     messageId = msg.messageId,                     visibilityTime = target                   }-          liftIO $ writeIORef lastVtRef updated.visibilityTime+          case updated of+            Nothing -> pure ()+            Just updatedMessage -> liftIO $ writeIORef lastVtRef updatedMessage.visibilityTime       }  -- | Create an AckHandle for a message.
test/Shibuya/Adapter/Pgmq/ConfigSpec.hs view
@@ -1,6 +1,8 @@ module Shibuya.Adapter.Pgmq.ConfigSpec (spec) where -import Pgmq.Types (parseQueueName, parseRoutingKey)+import Data.Either (isLeft, isRight)+import Pgmq.Types (parseRoutingKey)+import Shibuya.Adapter.Pgmq (parseQueueName) import Shibuya.Adapter.Pgmq.Config import Test.Hspec @@ -12,6 +14,7 @@   validateConfigSpec   deadLetterTargetSpec   smartConstructorSpec+  queueNameBoundarySpec  -- | Tests for defaultConfig defaultConfigSpec :: Spec@@ -173,3 +176,10 @@     it "sets includeMetadata correctly" $ do       let config = topicDeadLetter routingKey False       config.includeMetadata `shouldBe` False++queueNameBoundarySpec :: Spec+queueNameBoundarySpec = describe "parseQueueName" $ do+  it "accepts lowercase names and rejects uppercase and empty names" $ do+    parseQueueName "orders" `shouldSatisfy` isRight+    parseQueueName "Orders" `shouldSatisfy` isLeft+    parseQueueName "" `shouldSatisfy` isLeft
test/Shibuya/Adapter/Pgmq/IntegrationSpec.hs view
@@ -26,9 +26,12 @@ import Shibuya.Adapter.Pgmq.Config   ( PgmqAdapterConfig (..),     PollingConfig (..),+    defaultConfig,     defaultPollRetryConfig,   ) import Shibuya.Adapter.Pgmq.Convert (pgmqMessageToEnvelope)+import Shibuya.Adapter.Pgmq.Internal (mkLease)+import Shibuya.Core.Lease (Lease (..)) import Shibuya.Core.Types (Envelope (..)) import System.Environment (lookupEnv) import Test.Hspec@@ -236,6 +239,44 @@             }       pure $ Vector.length msgs     count `shouldBe` 1++  it "lease extension is a no-op after the message is deleted" $ \TestFixture {pool, queueName, dlqName = _} -> do+    runPgmqSession pool $ do+      _ <-+        Sessions.sendMessage $+          SendMessage+            { queueName = queueName,+              messageBody = MessageBody (String "lease-race-test"),+              delay = Just 0+            }+      pure ()++    runAdapterIO pool $ do+      msgs <-+        PgmqEff.readMessage $+          ReadMessage+            { queueName = queueName,+              delay = 30,+              batchSize = Just 1,+              conditional = Nothing+            }+      case Vector.uncons msgs of+        Just (msg, _) -> do+          lease <- mkLease (defaultConfig queueName) msg+          _ <- PgmqEff.deleteMessage (MessageQuery queueName msg.messageId)+          lease.leaseExtend 30+        Nothing -> liftIO $ expectationFailure "Expected one message to construct a lease"++    remaining <-+      runPgmqSession pool $+        Sessions.readMessage $+          ReadMessage+            { queueName = queueName,+              delay = 30,+              batchSize = Just 1,+              conditional = Nothing+            }+    Vector.length remaining `shouldBe` 0  -- | Retry handling tests (simulating AckRetry behavior) retryHandlingSpec :: SpecWith TestFixture