-
Notifications
You must be signed in to change notification settings - Fork 15
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
Add support for flushing the pool #16
Conversation
Sorry for the delayed response. Have you considered leaving the pool package as it is, but wrap it in something like the following: data FlushablePool =
FlushablePool
{-| Pool size. -}
Int
{-| Connection settings. -}
Hasql.Connection.Settings
{-| Pool var. -}
(MVar Hasql.Pool.Pool)
flush :: FlushablePool -> IO ()
flush (FlushablePool size settings var) = do
pool <- takeMVar var
Hasql.Pool.release pool
newPool <- Hasql.Pool.acquire size settings
putMVar var newPool |
Yes, I went for a similar approach (using an But the approach is fundamentally flawed in that the effective connection limit becomes EDIT: To be a bit more explicit: If the connection pool is fully loaded, and there are some long running queries, we'd exceed the limit on the connection count while any of the long running queries prior to releasing the pool are in flight. Congrats on the pgenie release btw! (And I understand you've been busy) |
Makes sense. Give me some time to review the PR.
Thanks :) |
Oh I should add that there's a follow-up change I want to make to allow timing out connection acquisition (I've filed it here PostgREST#4 for now, didn't want to keep piling on.) I'd understand in general if you want to keep this package more bare-bones, particularly considering its recent simplification. It would be ok (even if not ideal) for us to "properly" fork as say (Just mentioning this to warn you that this might not be the end of it, since that information might factor into deciding whether you want to merge this individual change.) |
I'm okay with merging the so far discussed updates to the library. I see no point in breeding libraries when we agree on the direction. Also since clearly you have a popular and actively maintained use-case if you wish I can add you as a co-maintainer. Let's just agree to keep initiating discussions like the one we're having now before making design changes. Back to the PR. Here's a thought: why don't we make Regarding the timeout. Give a try to the Any way, please give it some testing. Or even better, PR with some tests for it, if you will. If we discover that |
Yes that sounds great, somehow I took it as a given that
I think it's a different kind of timeout: We'd like to be able to bail out of waiting for a connection to be made available by the pool, while to my understanding the old timeout behaviour was about timing out idle connections. I'll file my change for that so we can discuss it there. |
-- | Alive. | ||
poolAlive :: TVar Bool | ||
-- | Whether to return a connection to the pool. | ||
poolReuseToggle :: TVar (TVar ReuseConnection) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm at a bit of a loss how to name this well. I went for very explicit naming for the purposes of making the PR understandable for now, hopefully we can find something better?
Connections created before calling 'flush' won't be reused afterwards.
Alright! I've merged all the changes and released it as 0.8. Nice work and thanks for your contributions! |
Whoa! Thanks |
"Flushing the pool" is close to what "releasing the pool" did in versions < 0.6, except it also ensures that in-flight connections don't get returned to the pool.
Does this seem like a useful feature? I fully understand if you'd prefer to keep the library simpler.
For context, I'm trying to upgrade PostgREST from hasql-pool 0.5, and PostgREST relies (brokenly) on being able to flush the pool via
release
. That's because it sets some per-connection variables, and needs to be able to update those values for new requests. (I make no claims as to whether that's a particularly sensible approach.)This isn't necessarily the simplest/cleanest way to do it. An alternative I'm aware of would be to track e.g. a
poolGeneration :: TVar Int
and compare the acquisition generation to the current generation to determine whether to return a connection to the pool. That has the theoretical downside thatInt
is bounded...