Skip to content

Commit deabcf2

Browse files
committed
Do not exceed the maximum number of resources
1 parent 3a1204b commit deabcf2

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* `destroyResource` no longer ignores exceptions thrown from resource releasing
77
functions.
88
* Change the default number of stripes to 1.
9+
* Do not exceed the maximum number of resources if the number of stripes does
10+
not divide it.
911

1012
# resource-pool-0.4.0.0 (2023-01-16)
1113
* Require `poolMaxResources` to be not smaller than the number of stripes.

src/Data/Pool/Internal.hs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ defaultPoolConfig
7575
-> (a -> IO ())
7676
-- ^ The action that destroys an existing resource.
7777
-> Double
78-
-- ^ The amount of seconds for which an unused resource is kept around. The
78+
-- ^ The number of seconds for which an unused resource is kept around. The
7979
-- smallest acceptable value is @0.5@.
8080
--
8181
-- /Note:/ the elapsed time before destroying a resource may be a little
@@ -84,9 +84,8 @@ defaultPoolConfig
8484
-- ^ The maximum number of resources to keep open __across all stripes__. The
8585
-- smallest acceptable value is @1@ per stripe.
8686
--
87-
-- /Note:/ for each stripe the number of resources is divided by the number of
88-
-- stripes and rounded up, hence the pool might end up creating up to @N - 1@
89-
-- resources more in total than specified, where @N@ is the number of stripes.
87+
-- /Note:/ if the number of stripes does not divide the number of resources,
88+
-- some of the stripes will have 1 more resource available than the others.
9089
-> PoolConfig a
9190
defaultPoolConfig create free cacheTTL maxResources =
9291
PoolConfig
@@ -99,10 +98,10 @@ defaultPoolConfig create free cacheTTL maxResources =
9998

10099
-- | Set the number of stripes (sub-pools) in the pool.
101100
--
102-
-- If not explicitly set, the default amount of stripes is 1, which should be
101+
-- If not explicitly set, the default number of stripes is 1, which should be
103102
-- good for typical use (when in doubt, profile your application first).
104103
--
105-
-- If set to 'Nothing', the pool will create the amount of stripes equal to the
104+
-- If set to 'Nothing', the pool will create the number of stripes equal to the
106105
-- number of capabilities.
107106
--
108107
-- /Note:/ usage of multiple stripes reduces contention, but can also result in
@@ -129,12 +128,13 @@ newPool pc = do
129128
error "numStripes must be at least 1"
130129
when (poolMaxResources pc < numStripes) $ do
131130
error "poolMaxResources must not be smaller than numStripes"
132-
pools <- fmap (smallArrayFromListN numStripes) . forM [1 .. numStripes] $ \n -> do
131+
let mkArray = fmap (smallArrayFromListN numStripes)
132+
pools <- mkArray . forM (stripeResources numStripes) $ \(n, resources) -> do
133133
ref <- newIORef ()
134134
stripe <-
135135
newTVarIO
136136
Stripe
137-
{ available = poolMaxResources pc `quotCeil` numStripes
137+
{ available = resources
138138
, cache = []
139139
, queue = Empty
140140
, queueR = Empty
@@ -161,10 +161,15 @@ newPool pc = do
161161
, reaperRef = ref
162162
}
163163
where
164-
quotCeil :: Int -> Int -> Int
165-
quotCeil x y =
166-
-- Basically ceiling (x / y) without going through Double.
167-
let (z, r) = x `quotRem` y in if r == 0 then z else z + 1
164+
stripeResources :: Int -> [(Int, Int)]
165+
stripeResources numStripes =
166+
let (base, rest) = quotRem (poolMaxResources pc) numStripes
167+
in zip [1 .. numStripes] $ addRest (replicate numStripes base) rest
168+
where
169+
addRest [] = error "unreachable"
170+
addRest acc@(r : rs) = \case
171+
0 -> acc
172+
rest -> r + 1 : addRest rs (rest - 1)
168173

169174
-- Collect stale resources from the pool once per second.
170175
collector pools = forever $ do

0 commit comments

Comments
 (0)