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

Connection pool #177

Merged
merged 26 commits into from
Oct 16, 2022
Merged

Connection pool #177

merged 26 commits into from
Oct 16, 2022

Conversation

moigagoo
Copy link
Owner

Alternative approach to #175

This is an attempt to come up with a simpler, more explicit pool implementation. The general concept: #175 (comment)

tests/config.nims Outdated Show resolved Hide resolved
@moigagoo
Copy link
Owner Author

@PhilippMDoerner please take a look at this PR. I've only implemented Pool for SQLite so far, just to test-drive the concept.

So far, the concept looks viable. I've tested it against concurrent access, seems to work.

Two policies for pool exchaustion were implemented: raise and extend. You can reset the pool after extension.

src/norm/pool.nim Outdated Show resolved Hide resolved
@PhilippMDoerner
Copy link
Collaborator

PhilippMDoerner commented Oct 15, 2022

Do you have any plans yet on if you want to have a shared module with all key procs / if you want to make this module generic?
The only thing I can see so far is the differing implementations on getDb between the sqlite and the postgres module. Feels tempting to have a single generic pool module, import and export that in both sqlite/postgres and use mixin getDb wherever getDb is used.

@moigagoo
Copy link
Owner Author

moigagoo commented Oct 15, 2022

@PhilippMDoerner

Do you have any plans yet on if you want to have a shared module with all key procs / if you want to make this module generic?
The only thing I can see so far is the differing implementations on getDb between the sqlite and the postgres module. Feels tempting to have a single generic pool module, import and export that in both sqlite/postgres and use mixin getDb wherever getDb is used.

I would prefer a single module but so far I can't see how I can do that. If I have a wrapper type DbConn = sqlite.DbConn | postgres.DbConn, I get these “ambigous call” errors because it's now unclear what newSeq[DbConn]() or close conn means. The compiler can't decide which DbConn I mean here.

So I'm OK to either have sqlite/pool and postgres/pool or just put the pool code into sqlite and postgres modules.

@PhilippMDoerner
Copy link
Collaborator

PhilippMDoerner commented Oct 15, 2022 via email

@moigagoo
Copy link
Owner Author

@PhilippMDoerner sure, I hate copy-pasted code too. I've tried using generics, to no avail so far. I'll give it some more thought.

Do I have your approval on the concept in general?

src/norm/pool.nim Outdated Show resolved Hide resolved
@moigagoo moigagoo linked an issue Oct 15, 2022 that may be closed by this pull request
@moigagoo moigagoo added the enhancement New feature or request label Oct 16, 2022
Copy link
Collaborator

@PhilippMDoerner PhilippMDoerner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good to me. I'm personally a fan of the "borrow/recycle" naming since "borrow" indicates that you're supposed to return the connection, but "pop/add" suits the general idea that the user can do whatever they want with the pool, you're just providing some utility procs to deal with it.

Though I do disagree with the doc comment changes from ref object to Model as stated in the comment for it.

src/norm/pool.nim Outdated Show resolved Hide resolved
src/norm/private/postgres/rowutils.nim Show resolved Hide resolved
src/norm/pool.nim Outdated Show resolved Hide resolved
@PhilippMDoerner
Copy link
Collaborator

Sidenote!
It could make sense to add a "warn" log or the like to the add proc if the amount of connections in there exceeds a specified multiple of the pools default size.
If, for example, the pool contains 1000x the amount of connections that the pool was originally sized for, I'd assume something is fishy.

changelog.md Outdated Show resolved Hide resolved
@moigagoo
Copy link
Owner Author

moigagoo commented Oct 16, 2022

It could make sense to add a "warn" log or the like to the add proc if the amount of connections in there exceeds a specified multiple of the pools default size.
If, for example, the pool contains 1000x the amount of connections that the pool was originally sized for, I'd assume something is fishy.

Sounds like an interesting idea! Maybe make this number configurable with -d:normdPoolWarning=1000 with a default of 100?

@PhilippMDoerner
Copy link
Collaborator

PhilippMDoerner commented Oct 16, 2022

It could make sense to add a "warn" log or the like to the add proc if the amount of connections in there exceeds a specified multiple of the pools default size.
If, for example, the pool contains 1000x the amount of connections that the pool was originally sized for, I'd assume something is fishy.

Sounds like an interesting idea! Maybe make this number configurable with -d:normdPoolWarning=1000 with a default of 100?

I'd actually not provide a default if we do this via compiler-flag, that way only folks that want this kind of warning can opt into it, everybody else can just ignore it.
Further, this is actually the kind of log that would be most useful in production. You almost certainly won't encounter the kind of bug that would make you want to have this log in a staging environment, as these types of bugs tend to come around most likely when your system is under heavy load.

Thus I'd want to make this logging independent of how norm generally is dependent on the -d:normDebug flag.

@moigagoo
Copy link
Owner Author

'm personally a fan of the "borrow/recycle" naming since "borrow" indicates that you're supposed to return the connection, but "pop/add" suits the general idea that the user can do whatever they want with the pool, you're just providing some utility procs to deal with it.

I started with borrowDb and returned and ended up with pop and add because I suddenly realised that:

  1. Theoretically, you can add a connection that has never been in the pool. So it's not necessarily returning, it may be just adding.
  2. Pop and add are primitives just like pop and add for a seq. So it may be a good idea to name them similarly to their seq counterparts.

@moigagoo moigagoo marked this pull request as draft October 16, 2022 10:44
@moigagoo moigagoo changed the title [WIP] Connection pool Connection pool Oct 16, 2022
@moigagoo moigagoo marked this pull request as ready for review October 16, 2022 12:55
pepExtend


proc newPool*[T: DbConn](defaultSize: Positive, poolExhaustedPolicy = pepRaise, getDbProc: proc: T = getDb): Pool[T] =
Copy link
Collaborator

@PhilippMDoerner PhilippMDoerner Oct 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does that actually get past the tests?
I'm a bit surprised, I'd have assumed that the compiler starts nagging about how it can't figure out whether to use getDb for sqlite or getDb for postgres

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that the tests ran through, it actually does work... I'm so confused. Oh well, nice to see it function!

@moigagoo
Copy link
Owner Author

@PhilippMDoerner OK I'm ready to merge. I've decided not to add logging for now as this is would slow me down and this can be safely added later. This has little to do with pooling per se, it's more about adding a compilation flag and modifying the logging proc and then putting it all together.

If you don't see any blockers, I'll merge the PR.

@PhilippMDoerner
Copy link
Collaborator

Looks good! Really happy to see norm have connection pooling!

@moigagoo moigagoo merged commit b9ec96c into develop Oct 16, 2022
@moigagoo moigagoo deleted the feature/connection_pool branch October 16, 2022 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[FR] connection pooling
2 participants