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

why acquireRetries has been removed from hikari #312

Closed
jayashsam opened this issue Apr 26, 2015 · 3 comments
Closed

why acquireRetries has been removed from hikari #312

jayashsam opened this issue Apr 26, 2015 · 3 comments
Labels

Comments

@jayashsam
Copy link

Can you please tell me why acquireRetries has been removed from hikari? Because I have gone through post Removal of acquireIncrement and acquireRetryDelay but couln't found anything about acquireRetries removal anywhere.

@brettwooldridge
Copy link
Owner

Many other pools create ("acquire") new connections on the user's thread, with settings for acquire timeout, acquire retries, and acquire retry delay. That kind of acquisition model presents several issues:

Issue 1: Load

A large number of request threads can generate significant connection creation load on the database because threads are 1:1 with connection attempts.

Issue 2: Timeouts

Pools with this model generally cannot provide deterministic timeouts to the application. Typically there is a separate connection timeout that applies when the pool is full.

If an application wants a deterministic timeout, the user must try configure the acquire timeout, acquire retries, and acquire retry delay to add up to the same value as connection timeout. But this can result in overly short acquisition timeouts or too few retries.

For example, if the user wants to guarantee that they either get a connection in 5 seconds, or they timeout. Obviously, they set connection timeout to 5 seconds. But how to set acquire timeout and acquire retries? 3 retries of 1 second each, with a 1 second delay between? Probably 1 second is not enough to complete a connection under load. 2 retries of 1250ms, with a 1250ms delay? The user should not have to configure the pool at such a low-level.

Additionally, if you later decide to increase the connection timeout to 8 seconds, you then have to rethink/recalculate how you want to redistribute acquire retries, delays, and timeouts.

Issue 3: Single-mindedness

Lastly, pools following the model of utilizing user-threads for acquisition must make a branch decision early -- wait for connection to return to the pool or, try to acquire a new connection. And once this decision is made, it cannot be unmade.

Imagine that a thread comes into the pool, and seeing that no idle connections are available, goes down the "acquire" path. The thread starts trying to create a connection, possibly timing out under load and "retrying". What if a connection was returned to the pool just 10 milliseconds "too late" -- 10ms after the above thread had just decided to create a new connection? Now there is a connection available in the pool, but the user's thread is busy trying to create a connection and cannot utilize it.

The HikariCP Model

The alternative is asynchronous connection acquisition. Basically, it works like this:

  • A thread coming into the pool checks for an available idle connection,
  • If there is a connection available it takes it and returns,
  • If there is no connection available, it queues a request to a dedicated thread to go create a new connection in the pool, then blocks on the pool collection

What are the benefits?

Benefit 1: Low-load

Because there is a dedicated thread for creating connections, and a queue of new creation requests, a sudden spike of requests cannot overload the database with connection attempts. New connections will be created as fast as the database is capable of creating them.

Benefit 2: Accurate Timeouts

Because the requesting thread blocks on the primary pool collection, an accurate timeout is possible (generally +/- 2ms). The user does not need to worry about matching acquire retries and acquire timeout to standard connection timeouts.

Benefit 3: No single-mindedness

If a connection is returned to the pool while a request thread is waiting in the pool, the thread awakens immediately to get the connection. Alternatively, if the dedicated connection creation thread completes first, the connection added to the pool also awakens the waiting thread. The user does not need to consider whether a call to getConnection() acquires a connection existing or acquires a newly created connection.

Back to acquireRetries...

Without a concept of acquireRetries, how long does the dedicated thread continue to try to create a new connection? Forever. The background creation thread will continue to try to add a connection to the pool forever, or until one of three conditions is met:

  • The pool is at, or has reached maximumPoolSize. I.e. adding a new connection is not possible.
  • The pool now has idle connections. I.e. there are now available connections, so the need to grow the pool has disappeared.
  • The connection is successfully created and added to the pool.

HikariCP's dedicated connection-creation executor thread employs a gradual back-off delay when connection attempts are failing; eventually reaching a maximum retry delay of connectionTimeout / 2 milliseconds.

@0xAxPx
Copy link

0xAxPx commented Dec 5, 2018

Leave this here - https://stackoverflow.com/questions/53633312/handle-a-hicaricp-oracle-connection-attempts
As I got it, in my case, if first connection failed, dedicated thread will continue to try to create a new connection? But why the number of attempts is 20?

@brettwooldridge
Copy link
Owner

@AlexPeshkov The number of attempt should be infinite, spaced approximately 1.5 seconds apart.

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

No branches or pull requests

3 participants