-
Notifications
You must be signed in to change notification settings - Fork 57
Description
When using pool to manage a series of PostgreSQL connections (via postgresql-simple), I've found that idle connections are not being reaped. After doing some digging, it appears that the reaper thread is being killed almost immediately, which I've linked to the execution of the finaliser attached to the internal fin IORef. I've no doubt that this is an issue with my code and not pool, but was wondering if I might find some help here. While I've not managed to produce a minimal reproducing test case, I have details about what I'm doing:
- I'm wrapping the pool in a
newtype, as innewtype MyPool = MyPool (Pool PG.Connection)and building one withfmapviz.
MyPool <$>
createPool PG.createConnection PG.closeConnection noOfStripes maxIdleTime perStripe- The above function results in the following core. To my inexperienced eyes, it doesn't suggest any cheeky unpacking/losing of the
IORefby GHC (which to my inexperienced brain is what would trigger a GHC and subsequent finalizer running, no?):
createPostgreSQLConnectionPool
:: PostgreSQLConfiguration
-> PostgreSQLConnectionPoolConfiguration
-> IO PostgreSQLConnectionPool
[GblId, Arity=2, Str=DmdType]
createPostgreSQLConnectionPool =
\ (ds_doFL :: PostgreSQLConfiguration)
(ds1_doFM :: PostgreSQLConnectionPoolConfiguration) ->
case ds_doFL
of _ [Occ=Dead]
{ PostgreSQLConfiguration ds2_doFN ds3_doFO ds4_doFP ds5_doFQ
ds6_doFR ->
case ds1_doFM
of _ [Occ=Dead]
{ PostgreSQLConnectionPoolConfiguration ds7_doFS ds8_doFT
ds9_doFU ->
let {
closePostgreSQL_anEf :: PG.Connection -> IO ()
[LclId, Str=DmdType]
closePostgreSQL_anEf =
\ (conn_anEg :: PG.Connection) ->
>>
@ IO
GHC.Base.$fMonadIO
@ ()
@ ()
(putStrLn
(ghc-prim-0.4.0.0:GHC.CString.unpackCString#
"[PG] Closing connection"#))
(PG.close conn_anEg) } in
let {
connectToPostgreSQL'_anEe :: IO PG.Connection
[LclId, Str=DmdType]
connectToPostgreSQL'_anEe =
>>
@ IO
GHC.Base.$fMonadIO
@ ()
@ PG.Connection
(putStrLn
(ghc-prim-0.4.0.0:GHC.CString.unpackCString#
"[PG] Creating connection"#))
(PG.connect
(case PG.defaultConnectInfo
of _ [Occ=Dead]
{ PG.ConnectInfo ds10_doG0 ds11_doG1 ds12_doG2 ds13_doG3
ds14_doG4 ->
Database.PostgreSQL.Simple.Internal.ConnectInfo
ds2_doFN
(fromIntegral
@ Int
@ GHC.Word.Word16
GHC.Real.$fIntegralInt
GHC.Word.$fNumWord16
ds3_doFO)
ds4_doFP
ds5_doFQ
ds6_doFR
})) } in
<$>
@ (Pool.Pool PG.Connection)
@ PostgreSQLConnectionPool
@ IO
GHC.Base.$fFunctorIO
((\ (tpl_B1 :: Pool.Pool PG.Connection) -> tpl_B1)
`cast` (<Pool.Pool PG.Connection>_R
-> Sym
Company.PostgreSQL.Internal.Trans.NTCo:PostgreSQLConnectionPool[0]
:: (Pool.Pool PG.Connection -> Pool.Pool PG.Connection)
~R# (Pool.Pool PG.Connection -> PostgreSQLConnectionPool)))
(Pool.createPool
@ PG.Connection
connectToPostgreSQL'_anEe
closePostgreSQL_anEf
ds7_doFS
(fromIntegral
@ Int
@ time-1.5.0.1:Data.Time.Clock.UTC.NominalDiffTime
GHC.Real.$fIntegralInt
time-1.5.0.1:Data.Time.Clock.UTC.$fNumNominalDiffTime
ds8_doFT)
ds9_doFU)
}
}
- The created pool is being used to run a transformer stack, as in
runPostgreSQL pool, and is working just fine in every other regard, so it seems like thefinis the only part of the structure being GC'd (again, assuming that this is the cause of the finaliser's running). - To be clear, removing the call to
mkWeakIORefcauses the reaper to work correctly. Furthermore, the local pool finalizers can be left in place without affecting its working. Lastly, usingaddFinalizerfromSystem.Mem.Weak(as was done in a previous version of this library, I believe) does not help either (again, perhaps it was stupid to assume it would).
Thanks in advance for any advice and apologies for not providing a minimal working example; I am struggling to find out exactly what I'm doing that's causing this. If there is any other information I can provide in the mean time I am happy to oblige to try and crack this.