11package tech .ydb .jdbc .context ;
22
33import java .sql .SQLException ;
4+ import java .util .Map ;
45import java .util .Objects ;
6+ import java .util .concurrent .atomic .AtomicInteger ;
57import java .util .logging .Level ;
68import java .util .logging .Logger ;
79
810import tech .ydb .core .grpc .GrpcTransport ;
11+ import tech .ydb .core .grpc .GrpcTransportBuilder ;
912import tech .ydb .jdbc .exception .YdbConfigurationException ;
13+ import tech .ydb .jdbc .settings .ParsedProperty ;
1014import tech .ydb .jdbc .settings .YdbClientProperties ;
15+ import tech .ydb .jdbc .settings .YdbClientProperty ;
1116import tech .ydb .jdbc .settings .YdbConnectionProperties ;
17+ import tech .ydb .jdbc .settings .YdbConnectionProperty ;
1218import tech .ydb .jdbc .settings .YdbOperationProperties ;
1319import tech .ydb .scheme .SchemeClient ;
1420import tech .ydb .table .TableClient ;
21+ import tech .ydb .table .impl .PooledTableClient ;
22+ import tech .ydb .table .rpc .grpc .GrpcTableRpc ;
1523
1624/**
1725 *
2129public class YdbContext implements AutoCloseable {
2230 private static final Logger LOGGER = Logger .getLogger (YdbContext .class .getName ());
2331
32+ private static final int SESSION_POOL_DEFAULT_MIN_SIZE = 0 ;
33+ private static final int SESSION_POOL_DEFAULT_MAX_SIZE = 50 ;
34+ private static final int SESSION_POOL_RESIZE_STEP = 50 ;
35+ private static final int SESSION_POOL_RESIZE_THRESHOLD = 10 ;
36+
2437 private final YdbConfig config ;
2538
2639 private final GrpcTransport grpcTransport ;
27- private final TableClient tableClient ;
40+ private final PooledTableClient tableClient ;
2841 private final SchemeClient schemeClient ;
42+ private final boolean autoResizeSessionPool ;
43+
44+ private final AtomicInteger connectionsCount = new AtomicInteger ();
2945
30- private YdbContext (YdbConfig config , GrpcTransport grpcTransport , TableClient tableClient ) {
46+ private YdbContext (YdbConfig config , GrpcTransport transport , PooledTableClient tableClient , boolean autoResize ) {
3147 this .config = config ;
32- this .grpcTransport = Objects .requireNonNull (grpcTransport );
48+ this .grpcTransport = Objects .requireNonNull (transport );
3349 this .tableClient = Objects .requireNonNull (tableClient );
34- this .schemeClient = SchemeClient .newClient (grpcTransport ).build ();
50+ this .schemeClient = SchemeClient .newClient (transport ).build ();
51+ this .autoResizeSessionPool = autoResize ;
3552 }
3653
3754 public String getDatabase () {
@@ -50,6 +67,10 @@ public String getUrl() {
5067 return config .getUrl ();
5168 }
5269
70+ public int getConnectionsCount () {
71+ return connectionsCount .get ();
72+ }
73+
5374 public YdbOperationProperties getOperationProperties () {
5475 return config .getOperationProperties ();
5576 }
@@ -65,20 +86,90 @@ public void close() {
6586 }
6687 }
6788
89+ public void register () {
90+ int actual = connectionsCount .incrementAndGet ();
91+ int maxSize = tableClient .sessionPoolStats ().getMaxSize ();
92+ if (autoResizeSessionPool && actual > maxSize - SESSION_POOL_RESIZE_THRESHOLD ) {
93+ int newSize = maxSize + SESSION_POOL_RESIZE_STEP ;
94+ if (maxSize == tableClient .sessionPoolStats ().getMaxSize ()) {
95+ tableClient .updatePoolMaxSize (newSize );
96+ }
97+ }
98+ }
99+
100+ public void deregister () {
101+ int actual = connectionsCount .decrementAndGet ();
102+ int maxSize = tableClient .sessionPoolStats ().getMaxSize ();
103+ if (autoResizeSessionPool && maxSize > SESSION_POOL_RESIZE_STEP ) {
104+ if (actual < maxSize - SESSION_POOL_RESIZE_STEP - 2 * SESSION_POOL_RESIZE_THRESHOLD ) {
105+ int newSize = maxSize - SESSION_POOL_RESIZE_STEP ;
106+ if (maxSize == tableClient .sessionPoolStats ().getMaxSize ()) {
107+ tableClient .updatePoolMaxSize (newSize );
108+ }
109+ }
110+ }
111+ }
112+
68113 public static YdbContext createContext (YdbConfig config ) throws SQLException {
69114 try {
70115 YdbConnectionProperties connProps = config .getConnectionProperties ();
71116 YdbClientProperties clientProps = config .getClientProperties ();
72117
73118 LOGGER .log (Level .INFO , "Creating new YDB connection to {0}" , connProps .getConnectionString ());
74119
75- GrpcTransport grpcTransport = connProps .toGrpcTransport ();
76-
77- TableClient tableClient = clientProps .toTableClient (grpcTransport );
120+ GrpcTransport grpcTransport = buildGrpcTransport (connProps );
121+ PooledTableClient .Builder tableClient = PooledTableClient .newClient (
122+ GrpcTableRpc .useTransport (grpcTransport )
123+ );
124+ boolean autoResize = buildTableClient (tableClient , clientProps );
78125
79- return new YdbContext (config , grpcTransport , tableClient );
126+ return new YdbContext (config , grpcTransport , tableClient . build (), autoResize );
80127 } catch (Exception ex ) {
81128 throw new YdbConfigurationException ("Cannot connect to YDB" , ex );
82129 }
83130 }
131+
132+ public static GrpcTransport buildGrpcTransport (YdbConnectionProperties props ) {
133+ GrpcTransportBuilder builder = GrpcTransport .forConnectionString (props .getConnectionString ());
134+ for (Map .Entry <YdbConnectionProperty <?>, ParsedProperty > entry : props .getParams ().entrySet ()) {
135+ if (entry .getValue () != null ) {
136+ entry .getKey ().getSetter ().accept (builder , entry .getValue ().getParsedValue ());
137+ }
138+ }
139+
140+ if (props .hasStaticCredentials ()) {
141+ builder = builder .withAuthProvider (props .getStaticCredentials ());
142+ }
143+
144+ return builder .build ();
145+ }
146+
147+ private static boolean buildTableClient (TableClient .Builder builder , YdbClientProperties props ) {
148+ for (Map .Entry <YdbClientProperty <?>, ParsedProperty > entry : props .getParams ().entrySet ()) {
149+ if (entry .getValue () != null ) {
150+ entry .getKey ().getSetter ().accept (builder , entry .getValue ().getParsedValue ());
151+ }
152+ }
153+
154+ ParsedProperty minSizeConfig = props .getProperty (YdbClientProperty .SESSION_POOL_SIZE_MIN );
155+ ParsedProperty maxSizeConfig = props .getProperty (YdbClientProperty .SESSION_POOL_SIZE_MAX );
156+
157+ if (minSizeConfig == null && maxSizeConfig == null ) {
158+ return true ;
159+ }
160+
161+ int minSize = SESSION_POOL_DEFAULT_MIN_SIZE ;
162+ int maxSize = SESSION_POOL_DEFAULT_MAX_SIZE ;
163+
164+ if (minSizeConfig != null ) {
165+ minSize = Math .max (0 , minSizeConfig .getParsedValue ());
166+ maxSize = Math .max (maxSize , minSize );
167+ }
168+ if (maxSizeConfig != null ) {
169+ maxSize = Math .max (minSize + 1 , maxSizeConfig .getParsedValue ());
170+ }
171+
172+ builder .sessionPoolSize (minSize , maxSize );
173+ return false ;
174+ }
84175}
0 commit comments