@@ -69,6 +69,10 @@ public class SessionPoolOptions {
69
69
/** Property for allowing mocking of session maintenance clock. */
70
70
private final Clock poolMaintainerClock ;
71
71
72
+ private final Duration waitForMultiplexedSession ;
73
+ private final boolean useMultiplexedSession ;
74
+ private final Duration multiplexedSessionMaintenanceDuration ;
75
+
72
76
private SessionPoolOptions (Builder builder ) {
73
77
// minSessions > maxSessions is only possible if the user has only set a value for maxSessions.
74
78
// We allow that to prevent code that only sets a value for maxSessions to break if the
@@ -93,6 +97,9 @@ private SessionPoolOptions(Builder builder) {
93
97
this .randomizePositionQPSThreshold = builder .randomizePositionQPSThreshold ;
94
98
this .inactiveTransactionRemovalOptions = builder .inactiveTransactionRemovalOptions ;
95
99
this .poolMaintainerClock = builder .poolMaintainerClock ;
100
+ this .useMultiplexedSession = builder .useMultiplexedSession ;
101
+ this .multiplexedSessionMaintenanceDuration = builder .multiplexedSessionMaintenanceDuration ;
102
+ this .waitForMultiplexedSession = builder .waitForMultiplexedSession ;
96
103
}
97
104
98
105
@ Override
@@ -123,7 +130,11 @@ public boolean equals(Object o) {
123
130
&& Objects .equals (this .randomizePositionQPSThreshold , other .randomizePositionQPSThreshold )
124
131
&& Objects .equals (
125
132
this .inactiveTransactionRemovalOptions , other .inactiveTransactionRemovalOptions )
126
- && Objects .equals (this .poolMaintainerClock , other .poolMaintainerClock );
133
+ && Objects .equals (this .poolMaintainerClock , other .poolMaintainerClock )
134
+ && Objects .equals (this .useMultiplexedSession , other .useMultiplexedSession )
135
+ && Objects .equals (
136
+ this .multiplexedSessionMaintenanceDuration , other .multiplexedSessionMaintenanceDuration )
137
+ && Objects .equals (this .waitForMultiplexedSession , other .waitForMultiplexedSession );
127
138
}
128
139
129
140
@ Override
@@ -148,7 +159,10 @@ public int hashCode() {
148
159
this .releaseToPosition ,
149
160
this .randomizePositionQPSThreshold ,
150
161
this .inactiveTransactionRemovalOptions ,
151
- this .poolMaintainerClock );
162
+ this .poolMaintainerClock ,
163
+ this .useMultiplexedSession ,
164
+ this .multiplexedSessionMaintenanceDuration ,
165
+ this .waitForMultiplexedSession );
152
166
}
153
167
154
168
public Builder toBuilder () {
@@ -271,6 +285,18 @@ long getRandomizePositionQPSThreshold() {
271
285
return randomizePositionQPSThreshold ;
272
286
}
273
287
288
+ boolean getUseMultiplexedSession () {
289
+ return useMultiplexedSession ;
290
+ }
291
+
292
+ Duration getMultiplexedSessionMaintenanceDuration () {
293
+ return multiplexedSessionMaintenanceDuration ;
294
+ }
295
+
296
+ Duration getWaitForMultiplexedSession () {
297
+ return waitForMultiplexedSession ;
298
+ }
299
+
274
300
public static Builder newBuilder () {
275
301
return new Builder ();
276
302
}
@@ -467,6 +493,9 @@ public static class Builder {
467
493
*/
468
494
private long randomizePositionQPSThreshold = 0L ;
469
495
496
+ private boolean useMultiplexedSession = false ;
497
+ private Duration multiplexedSessionMaintenanceDuration = Duration .ofDays (7 );
498
+ private Duration waitForMultiplexedSession = Duration .ofSeconds (10 );
470
499
private Clock poolMaintainerClock ;
471
500
472
501
private static Position getReleaseToPositionFromSystemProperty () {
@@ -669,6 +698,47 @@ Builder setPoolMaintainerClock(Clock poolMaintainerClock) {
669
698
return this ;
670
699
}
671
700
701
+ /**
702
+ * Sets whether the client should use multiplexed session or not. If set to true, the client
703
+ * optimises and runs multiple applicable requests concurrently on a single session. A single
704
+ * multiplexed session is sufficient to handle all concurrent traffic.
705
+ *
706
+ * <p>When set to false, the client uses the regular session cached in the session pool for
707
+ * running 1 concurrent transaction per session. We require to provision sufficient sessions by
708
+ * making use of {@link SessionPoolOptions#minSessions} and {@link
709
+ * SessionPoolOptions#maxSessions} based on the traffic load. Failing to do so will result in
710
+ * higher latencies.
711
+ */
712
+ Builder setUseMultiplexedSession (boolean useMultiplexedSession ) {
713
+ this .useMultiplexedSession = useMultiplexedSession ;
714
+ return this ;
715
+ }
716
+
717
+ @ VisibleForTesting
718
+ Builder setMultiplexedSessionMaintenanceDuration (
719
+ Duration multiplexedSessionMaintenanceDuration ) {
720
+ this .multiplexedSessionMaintenanceDuration = multiplexedSessionMaintenanceDuration ;
721
+ return this ;
722
+ }
723
+
724
+ /**
725
+ * This option is only used when {@link SessionPoolOptions#useMultiplexedSession} is set to
726
+ * true. If greater than zero, calls to {@link Spanner#getDatabaseClient(DatabaseId)} will block
727
+ * for up to the given duration while waiting for the multiplexed session to be created. The
728
+ * default value for this is 10 seconds.
729
+ *
730
+ * <p>If this is set to null or zero, the client does not wait for the session to be created,
731
+ * which means that the first read requests could see more latency, as they will need to wait
732
+ * until the multiplexed session has been created.
733
+ *
734
+ * <p>Note that we would need to use the option {@link SessionPoolOptions#waitForMinSessions} if
735
+ * we want a similar blocking behavior for the other sessions within the session pool.
736
+ */
737
+ Builder setWaitForMultiplexedSession (Duration waitForMultiplexedSession ) {
738
+ this .waitForMultiplexedSession = waitForMultiplexedSession ;
739
+ return this ;
740
+ }
741
+
672
742
/**
673
743
* Sets whether the client should automatically execute a background query to detect the dialect
674
744
* that is used by the database or not. Set this option to true if you do not know what the
0 commit comments