2626import java .net .URI ;
2727import java .net .URISyntaxException ;
2828import java .nio .file .Path ;
29+ import java .util .Map ;
30+ import java .util .concurrent .ConcurrentHashMap ;
2931import java .util .concurrent .Executors ;
3032import java .util .concurrent .ScheduledExecutorService ;
3133import java .util .concurrent .TimeUnit ;
@@ -41,6 +43,8 @@ public class JdbcConnectionManager
4143 private final ScheduledExecutorService executorService =
4244 Executors .newSingleThreadScheduledExecutor ();
4345
46+ private final Map <String , HikariDataSource > pools = new ConcurrentHashMap <>();
47+
4448 public JdbcConnectionManager (Jdbi jdbi , DataStoreConfiguration configuration )
4549 {
4650 this .jdbi = requireNonNull (jdbi , "jdbi is null" )
@@ -61,21 +65,18 @@ public Jdbi getJdbi(@Nullable String routingGroupDatabase)
6165 return jdbi ;
6266 }
6367
64- if (configuration .getMaxPoolSize () != null && configuration .getMaxPoolSize () > 0 ) {
65- HikariConfig hikariConfig = new HikariConfig ();
66- hikariConfig .setJdbcUrl (buildJdbcUrl (routingGroupDatabase ));
67- hikariConfig .setUsername (configuration .getUser ());
68- hikariConfig .setPassword (configuration .getPassword ());
69- if (configuration .getDriver () != null ) {
70- hikariConfig .setDriverClassName (configuration .getDriver ());
71- }
72- hikariConfig .setMaximumPoolSize (configuration .getMaxPoolSize ());
73- return Jdbi .create (new HikariDataSource (hikariConfig ))
68+ Integer maxPoolSize = configuration .getMaxPoolSize ();
69+ if (maxPoolSize != null && maxPoolSize > 0 ) {
70+ HikariDataSource ds = getOrCreateDataSource (routingGroupDatabase , maxPoolSize );
71+ return Jdbi .create (ds )
7472 .installPlugin (new SqlObjectPlugin ())
7573 .registerRowMapper (new RecordAndAnnotatedConstructorMapper ());
7674 }
7775
78- return Jdbi .create (buildJdbcUrl (routingGroupDatabase ), configuration .getUser (), configuration .getPassword ())
76+ return Jdbi .create (
77+ buildJdbcUrl (routingGroupDatabase ),
78+ configuration .getUser (),
79+ configuration .getPassword ())
7980 .installPlugin (new SqlObjectPlugin ())
8081 .registerRowMapper (new RecordAndAnnotatedConstructorMapper ());
8182 }
@@ -123,11 +124,51 @@ private void startCleanUps()
123124 executorService .scheduleWithFixedDelay (
124125 () -> {
125126 log .info ("Performing query history cleanup task" );
126- long created = System .currentTimeMillis () - TimeUnit .HOURS .toMillis (this .configuration .getQueryHistoryHoursRetention ());
127+ long created = System .currentTimeMillis ()
128+ - TimeUnit .HOURS .toMillis (this .configuration .getQueryHistoryHoursRetention ());
127129 jdbi .onDemand (QueryHistoryDao .class ).deleteOldHistory (created );
128130 },
129131 1 ,
130132 120 ,
131133 TimeUnit .MINUTES );
132134 }
135+
136+ private HikariDataSource getOrCreateDataSource (String routingGroupDatabase , int maxPoolSize )
137+ {
138+ return pools .compute (routingGroupDatabase , (key , existing ) -> {
139+ if (existing != null && !existing .isClosed ()) {
140+ return existing ;
141+ }
142+
143+ HikariConfig cfg = new HikariConfig ();
144+ cfg .setJdbcUrl (buildJdbcUrl (key ));
145+ cfg .setUsername (configuration .getUser ());
146+ cfg .setPassword (configuration .getPassword ());
147+ if (configuration .getDriver () != null ) {
148+ cfg .setDriverClassName (configuration .getDriver ());
149+ }
150+ cfg .setMaximumPoolSize (maxPoolSize );
151+ cfg .setPoolName ("gateway-ha-" + key );
152+
153+ return new HikariDataSource (cfg );
154+ });
155+ }
156+
157+ public void close ()
158+ {
159+ for (Map .Entry <String , HikariDataSource > e : pools .entrySet ()) {
160+ HikariDataSource ds = e .getValue ();
161+ if (ds != null && !ds .isClosed ()) {
162+ try {
163+ ds .close ();
164+ }
165+ catch (RuntimeException ex ) {
166+ log .warn (ex , "Failed to close datasource for key: %s" , e .getKey ());
167+ }
168+ }
169+ }
170+ pools .clear ();
171+
172+ executorService .shutdownNow ();
173+ }
133174}
0 commit comments