packages feed

hasql-pool 1.0.1 → 1.1

raw patch · 9 files changed

+70/−16 lines, 9 filesbinary-addedPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Hasql.Pool.Config: initSession :: Session () -> Setting
+ Hasql.Pool.Config.Defaults: initSession :: Session ()
+ Hasql.Pool.Observation: EstablishedConnectionReadyForUseReason :: ConnectionReadyForUseReason
+ Hasql.Pool.Observation: InitializationErrorTerminationReason :: QueryError -> ConnectionTerminationReason
+ Hasql.Pool.Observation: SessionFailedConnectionReadyForUseReason :: QueryError -> ConnectionReadyForUseReason
+ Hasql.Pool.Observation: SessionSucceededConnectionReadyForUseReason :: ConnectionReadyForUseReason
+ Hasql.Pool.Observation: data ConnectionReadyForUseReason
+ Hasql.Pool.Observation: instance GHC.Classes.Eq Hasql.Pool.Observation.ConnectionReadyForUseReason
+ Hasql.Pool.Observation: instance GHC.Show.Show Hasql.Pool.Observation.ConnectionReadyForUseReason
- Hasql.Pool.Observation: ReadyForUseConnectionStatus :: ConnectionStatus
+ Hasql.Pool.Observation: ReadyForUseConnectionStatus :: ConnectionReadyForUseReason -> ConnectionStatus

Files

CHANGELOG.md view
@@ -1,3 +1,8 @@+# 1.1++- `ReadyForUseConnectionStatus` got extended with the `ConnectionReadyForUseReason` details.+- `initSession` setting added.+ # 1  - Optional observability event stream added. Provides a flexible mechanism for monitoring the healthiness of the pool via logs and metrics.
+ diagrams-output/observation-status-model.png view

binary file changed (absent → 16434 bytes)

hasql-pool.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: hasql-pool-version: 1.0.1+version: 1.1 category: Hasql, Database, PostgreSQL synopsis: Pool of connections for Hasql homepage: https://github.com/nikita-volkov/hasql-pool@@ -10,8 +10,13 @@ copyright: (c) 2015, Nikita Volkov license: MIT license-file: LICENSE-extra-source-files: CHANGELOG.md+extra-source-files:+  CHANGELOG.md+  diagrams-output/*.png +extra-doc-files:+  diagrams-output/*.png+ source-repository head   type: git   location: git://github.com/nikita-volkov/hasql-pool.git@@ -41,6 +46,8 @@     MagicHash     MultiParamTypeClasses     MultiWayIf+    NoImplicitPrelude+    NoMonomorphismRestriction     NumericUnderscores     OverloadedStrings     ParallelListComp@@ -57,8 +64,6 @@     TypeFamilies     TypeOperators     UnboxedTuples-    NoImplicitPrelude-    NoMonomorphismRestriction    default-language: Haskell2010 
src/library/exposed/Hasql/Pool.hs view
@@ -60,7 +60,9 @@     -- | To stop the manager thread via garbage collection.     poolReaperRef :: IORef (),     -- | Action for reporting the observations.-    poolObserver :: Observation -> IO ()+    poolObserver :: Observation -> IO (),+    -- | Initial session to execute upon every established connection.+    poolInitSession :: Session.Session ()   }  -- | Create a connection-pool.@@ -98,7 +100,7 @@     -- When the pool goes out of scope, stop the manager.     killThread managerTid -  return $ Pool (Config.size config) (Config.connectionSettingsProvider config) acqTimeoutMicros agingTimeoutNanos maxIdletimeNanos connectionQueue capVar reuseVar reaperRef (Config.observationHandler config)+  return $ Pool (Config.size config) (Config.connectionSettingsProvider config) acqTimeoutMicros agingTimeoutNanos maxIdletimeNanos connectionQueue capVar reuseVar reaperRef (Config.observationHandler config) (Config.initSession config)   where     acqTimeoutMicros =       div (fromIntegral (diffTimeToPicoseconds (Config.acquisitionTimeout config))) 1_000_000@@ -164,15 +166,24 @@       now <- getMonotonicTimeNSec       id <- Uuid.nextRandom       poolObserver (ConnectionObservation id ConnectingConnectionStatus)-      connRes <- Connection.acquire settings-      case connRes of+      Connection.acquire settings >>= \case         Left connErr -> do           poolObserver (ConnectionObservation id (TerminatedConnectionStatus (NetworkErrorConnectionTerminationReason (fmap (Text.decodeUtf8With Text.lenientDecode) connErr))))           atomically $ modifyTVar' poolCapacity succ           return $ Left $ ConnectionUsageError connErr-        Right entry -> do-          poolObserver (ConnectionObservation id ReadyForUseConnectionStatus)-          onLiveConn reuseVar (Entry entry now now id)+        Right connection -> do+          Session.run poolInitSession connection >>= \case+            Left err -> do+              Connection.release connection+              case err of+                Session.QueryError _ _ (Session.ClientError details) -> do+                  poolObserver (ConnectionObservation id (TerminatedConnectionStatus (NetworkErrorConnectionTerminationReason (fmap (Text.decodeUtf8With Text.lenientDecode) details))))+                _ ->+                  poolObserver (ConnectionObservation id (TerminatedConnectionStatus (InitializationErrorTerminationReason err)))+              return $ Left $ SessionUsageError err+            Right () -> do+              poolObserver (ConnectionObservation id (ReadyForUseConnectionStatus EstablishedConnectionReadyForUseReason))+              onLiveConn reuseVar (Entry connection now now id)      onConn reuseVar entry = do       now <- getMonotonicTimeNSec@@ -206,11 +217,11 @@             return $ Left $ SessionUsageError err           _ -> do             returnConn-            poolObserver (ConnectionObservation (entryId entry) ReadyForUseConnectionStatus)+            poolObserver (ConnectionObservation (entryId entry) (ReadyForUseConnectionStatus (SessionFailedConnectionReadyForUseReason err)))             return $ Left $ SessionUsageError err         Right (Right res) -> do           returnConn-          poolObserver (ConnectionObservation (entryId entry) ReadyForUseConnectionStatus)+          poolObserver (ConnectionObservation (entryId entry) (ReadyForUseConnectionStatus SessionSucceededConnectionReadyForUseReason))           return $ Right res       where         returnConn =
src/library/exposed/Hasql/Pool/Config.hs view
@@ -10,6 +10,7 @@     Setting.staticConnectionSettings,     Setting.dynamicConnectionSettings,     Setting.observationHandler,+    Setting.initSession,   ) where 
src/library/exposed/Hasql/Pool/Config/Defaults.hs view
@@ -3,6 +3,7 @@ import qualified Hasql.Connection as Connection import Hasql.Pool.Observation (Observation) import Hasql.Pool.Prelude+import qualified Hasql.Session as Session  -- | -- 3 connections.@@ -38,3 +39,8 @@ -- > const (pure ()) observationHandler :: Observation -> IO () observationHandler = const (pure ())++-- |+-- > pure ()+initSession :: Session.Session ()+initSession = pure ()
src/library/exposed/Hasql/Pool/Observation.hs view
@@ -5,6 +5,7 @@ module Hasql.Pool.Observation where  import Hasql.Pool.Prelude+import qualified Hasql.Session as Session  -- | An observation of a change of the state of a pool. data Observation@@ -18,13 +19,15 @@   deriving (Show, Eq)  -- | Status of a connection.+--+-- <<diagrams-output/observation-status-model.png>> data ConnectionStatus   = -- | Connection is being established.     --     -- This is the initial status of every connection.     ConnectingConnectionStatus   | -- | Connection is established and not occupied.-    ReadyForUseConnectionStatus+    ReadyForUseConnectionStatus ConnectionReadyForUseReason   | -- | Is being used by some session.     --     -- After it's done the status will transition to 'ReadyForUseConnectionStatus' or 'TerminatedConnectionStatus'.@@ -33,6 +36,15 @@     TerminatedConnectionStatus ConnectionTerminationReason   deriving (Show, Eq) +data ConnectionReadyForUseReason+  = -- | Connection just got established.+    EstablishedConnectionReadyForUseReason+  | -- | Session execution ended with a failure that does not require a connection reset.+    SessionFailedConnectionReadyForUseReason Session.QueryError+  | -- | Session execution ended with success.+    SessionSucceededConnectionReadyForUseReason+  deriving (Show, Eq)+ -- | Explanation of why a connection was terminated. data ConnectionTerminationReason   = -- | The age timeout of the connection has passed.@@ -43,4 +55,6 @@     NetworkErrorConnectionTerminationReason (Maybe Text)   | -- | User has invoked the 'Hasql.Pool.release' procedure.     ReleaseConnectionTerminationReason+  | -- | Initialization session failure.+    InitializationErrorTerminationReason Session.QueryError   deriving (Show, Eq)
src/library/other/Hasql/Pool/Config/Config.hs view
@@ -4,6 +4,7 @@ import qualified Hasql.Pool.Config.Defaults as Defaults import Hasql.Pool.Observation (Observation) import Hasql.Pool.Prelude+import qualified Hasql.Session as Session  -- | Configufation for Hasql connection pool. data Config = Config@@ -12,7 +13,8 @@     agingTimeout :: DiffTime,     idlenessTimeout :: DiffTime,     connectionSettingsProvider :: IO Connection.Settings,-    observationHandler :: Observation -> IO ()+    observationHandler :: Observation -> IO (),+    initSession :: Session.Session ()   }  -- | Reasonable defaults, which can be built upon.@@ -24,5 +26,6 @@       agingTimeout = Defaults.agingTimeout,       idlenessTimeout = Defaults.idlenessTimeout,       connectionSettingsProvider = Defaults.dynamicConnectionSettings,-      observationHandler = Defaults.observationHandler+      observationHandler = Defaults.observationHandler,+      initSession = Defaults.initSession     }
src/library/other/Hasql/Pool/Config/Setting.hs view
@@ -5,6 +5,7 @@ import qualified Hasql.Pool.Config.Config as Config import Hasql.Pool.Observation (Observation) import Hasql.Pool.Prelude+import qualified Hasql.Session as Session  apply :: Setting -> Config -> Config apply (Setting run) = run@@ -86,3 +87,11 @@ observationHandler :: (Observation -> IO ()) -> Setting observationHandler x =   Setting (\config -> config {Config.observationHandler = x})++-- | Initial session.+--+-- Gets executed on every connection upon acquisition.+-- Lets you specify the connection-wide settings.+initSession :: Session.Session () -> Setting+initSession x =+  Setting (\config -> config {Config.initSession = x})