I believe we should change the strategy for how resources are allocated across stripes.
The next code allocates 16 resources, while the maximum number specified in the config is nine.
main :: IO ()
main = do
getNumCapabilities >>= print
ref <- newIORef @Int 0
pool <- newPool PoolConfig
{ createResource = atomicModifyIORef ref (\a -> (a + 1, a)) >>= print
, freeResource = const $ atomicModifyIORef ref ((,()) . pred)
, poolCacheTTL = 0.5
, poolMaxResources = 9
, poolNumStripes = Just 8
}
hSetBuffering stdout LineBuffering
forM_ @[] [1..200] \(_ :: Int) -> do
forkIO $ withResource pool \() -> threadDelay 1000000
threadDelay 2000000
This can play very badly when you for some reason reduce the number of available resources (for example, your database cannot accept so many connections), as in the example above from 16 to 9, but do not get the expected result.
I suggest adding an interface for manually distributing the number of resources across stripes and accepting not numStripes + maxResources, but something like [Int], where each element of the list is a stripe and the number is the amount of resources on this stripe
In hindsight looks like the decision of changing "resources per stripe" in the config to "resources across all stripes" was a mistake. I'm not sure how to back off of this now though :confused:
I believe we should change the strategy for how resources are allocated across stripes.
The next code allocates 16 resources, while the maximum number specified in the config is nine.
This can play very badly when you for some reason reduce the number of available resources (for example, your database cannot accept so many connections), as in the example above from 16 to 9, but do not get the expected result.
I suggest adding an interface for manually distributing the number of resources across stripes and accepting not numStripes + maxResources, but something like [Int], where each element of the list is a stripe and the number is the amount of resources on this stripe