Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Peek available pool resources without taking the resource? #29

Open
avanov opened this issue Mar 7, 2023 · 1 comment
Open

Peek available pool resources without taking the resource? #29

avanov opened this issue Mar 7, 2023 · 1 comment

Comments

@avanov
Copy link

avanov commented Mar 7, 2023

Subj, the original repository had a pull request that had it implemented for many years, and there are codebases that rely on that branch to feed stats periodically into statsd and alike. Though the current API assumes that the stats are only peekable on the acquired resources, which doesn't always fit existing use-cases where resources themselves shouldn't be tied to and affected by the stats middleware.

@avanov
Copy link
Author

avanov commented Mar 8, 2023

This shows how fragile the current reliance on Data.Pool.Internal may be for end users, if the API isn't provided by the library. I marked Data.Pool.Internal as Unstable below:

data Stats = Stats
    {   currentUsage  :: !Int
        -- ^ Current number of resources being used.
    ,   available     :: !Int
        -- ^ Total resources available for consumption.
    } deriving Show


stats :: Pool -> IO Stats
stats (Pool pool) = currentlyAvailablePerStripe >>= collect where
    -- attributes extraction and counting
    collect xs = pure $ Stats inUse avail where
        inUse = maxResources - avail
        avail = sum xs

    currentlyAvailablePerStripe = traverse id peekAvailable
    peekAvailable               = (fmap stripeAvailability) <$> allStripes    -- array of IO Int
    stripeAvailability ms       = maybe quotaPerStripe Unstable.available ms  -- if the stripe ref is uninitialised, count the default availability
    allStripes                  = peekStripe <$> Unstable.localPools pool     -- array of IO Maybe
    peekStripe                  = tryReadMVar . Unstable.stripeVar

    -- data from the pool
    quotaPerStripe              = maxResources `quotCeil` numStripes
    numStripes                  = length $ Unstable.localPools pool  -- can be 'sizeofSmallArray' but requires 'primitive' as dependency
    maxResources                = Unstable.poolMaxResources . Unstable.poolConfig $ pool
    quotCeil x y                = let (z, r) = x `quotRem` y in if r == 0 then z else z + 1  -- copied from 'Data.Pool.Internal'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant