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
fix(gateway-vertx): use cache for non-shared JDBC client #2570
base: master
Are you sure you want to change the base?
Conversation
Adding the default set of apiman jdbc drivers to vert.x. In addition cache non-shared clients (e.g. clients for basic-auth-policy) instead of creating a new once per request. Closes: #2569
Thanks. I considered this approach but discounted it for a few reasons:
I've backported a solution for my 3.x customers that allows them to include the JDBC driver externally via a workaround and some additional code, but I am not adding new features to 3.x upstream at this point. This will be fixed in the upstream properly with Apiman 4 (probably). The cache change is useful though by itself. |
Maybe a compromise is just to include the Postgres driver for now, but I'm still wary about compatibility issues and forcing a particular driver version. |
Passing run #957 ↗︎
Details:
This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. |
Thanks for the feedback Marc! The main problem we encountered was the client that was created again and again. |
Yeah, the way we get away with it is that we never distribute the project or code with those license-incompatible drivers. They are referenced only for test or development purposes such as generating DDL, etc. I'm probably going to drop some of them for upstream anyway, which should hopefully fix that issue entirely. Yet more things for me to consider in Apiman 4 I suppose. I'm not getting to spend as much time on it as I would like, but still trying to push ahead. |
OK, let's split this topic. I'll commit the cache enhancement separately, and then we can think separately about whether we should include any drivers in 3.x or just wait for Apiman 4 to avoid complicating things. |
//private static Map<> | ||
private JDBCClient jdbcClient; | ||
private static final Cache<String, JDBCClient> cache = Caffeine.newBuilder() | ||
.maximumSize(20) |
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.
Is 20 just a magic number?
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.
Yes, I thought it would maybe make scene to make this configurable but not sure if there is really a need for it.
Currently it would cache 20 clients (20 different db configs, I am not sure if we really have the need for more.)
If you would use the same db table for different basic-auth-policy configs it would be always the same client.
I've thought of a potential solution that's even better than the workaround I use for customers to allow an external JDBC driver, so I'll experiment with that later when I have some time 🤞. Posting this as a reminder to myself. |
I think that is a good idea. I can remove the drives from my commit if you want? |
Whichever you prefer, sounds good to me 🙏 |
I'm also trying to get rid of the old ES libraries that were dragged in during a contribution a few years ago which has massively bulked out the gateway. That's a WIP for Apiman 4 (usual caveats apply for time and money, etc). |
Okay I will do it and directly add the changelog here as well :) |
Okay, related thought... Is there any reason not to use a Vert.x shared connection pool any more? Can we generate a key for the Vert.x shared connection instead of caching our own? Thinking out loud here. |
For example, if we are not sure we can reliably create a key that will guarantee we don't mix up the wrong clients (which could be a problem with this enhancement anyway I guess). |
Also, should users of the JDBC client not be closing the connection themselves? Do we not make that available to them. |
Mhh you may be right about that, my vert.x knowledge is not that deep.
I was not totally sure if we really need a new instance of the client all the time:
|
Currently I cannot see in the logs that a client is close.
|
Yeah, this requires a careful look because if you get the cache key wrong, then you may end up mixing together unrelated SQL calls and that will break things in extremely confusing ways. I recall I avoided implementing caching at the time for that reason. That's why the comment references "jsonConfigs" as I was trying to figure out what needed to be included in the cache key to guarantee uniqueness. It might actually be easier to change the code calling this impl, not sure... I will try to look soon. |
I checked that as well and it seems to work as well. Without a dsName it uses a default name (which than would return the same client for all configs)
|
Question - why is the calling code not setting a Couple of thoughts: Wonder if we could just set a
In worst case it would end up creating more pools than needed if people pass in lots of different configuration permutations, but it should avoid ever accidentally getting caught out (e.g. user passes an extra option that means it's no longer compatible with the simple Thoughts? |
I think if we would use the complete config as cache key then we would´t need a shared client anyway? Only question is what happens with all the clients in the map? There would be no limit of different clients then? I think if we would create a unique dsName already here, it would be solved as well:
|
How would it work with your proposal. I don't see how we would otherwise
ensure there's no cache collision without something clumsy like a building
a string every time.
…On Wed, 19 Jul 2023, 12:10 Florian Volk, ***@***.***> wrote:
I think if we would use the complete config as cache key then we would´t
need a shared client anyway?
Then we could use a normal client (which ensures its created with a unique
id).
Only question is what happens with all the clients in the map? There would
be no limit of different clients then?
Not sure if this could cause problems?
------------------------------
I think if we would create a unique dsName already here, it would be
solved as well:
public IJdbcClient createStandalone(JdbcOptionsBean config) {
return new VertxJdbcClientImpl(vertx, config);
}
—
Reply to this email directly, view it on GitHub
<#2570 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADHMWO6QKAIHFVO3OAYPYDXQ66CTANCNFSM6AAAAAA2PSXBVY>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
I guess the problem is twofold:
The Apiman code is using non-shared in places it should probably use shared.
And are we breaking the non-shared case by some cache mappings (I think it
should be ok, but not sure).
…On Wed, 19 Jul 2023, 12:22 Marc Savy, ***@***.***> wrote:
How would it work with your proposal. I don't see how we would otherwise
ensure there's no cache collision without something clumsy like a building
a string every time.
On Wed, 19 Jul 2023, 12:10 Florian Volk, ***@***.***> wrote:
> I think if we would use the complete config as cache key then we would´t
> need a shared client anyway?
> Then we could use a normal client (which ensures its created with a
> unique id).
>
> Only question is what happens with all the clients in the map? There
> would be no limit of different clients then?
> Not sure if this could cause problems?
> ------------------------------
>
> I think if we would create a unique dsName already here, it would be
> solved as well:
>
> public IJdbcClient createStandalone(JdbcOptionsBean config) {
> return new VertxJdbcClientImpl(vertx, config);
> }
>
> —
> Reply to this email directly, view it on GitHub
> <#2570 (comment)>, or
> unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AADHMWO6QKAIHFVO3OAYPYDXQ66CTANCNFSM6AAAAAA2PSXBVY>
> .
> You are receiving this because you commented.Message ID:
> ***@***.***>
>
|
Ah, I did not explained it in a good way.
So we would create a shared client which is still unique and vertx would handle it for us. |
Description
Adding the default set of apiman jdbc drivers to vert.x. In addition cache non-shared clients (e.g. clients for basic-auth-policy) instead of creating a new once per request.
This is maybe not the perfect solution but I did not wanted to refactor the whole client logic as this may introduce additional bugs/breaking stuff.
Fixes #2569
Checklist