Skip to content

Commit d970a2c

Browse files
arpan14olavloite
andauthored
chore: add session pool options for multiplexed session. (#2960)
* fix: prevent illegal negative timeout values into thread sleep() method while retrying exceptions in unit tests. * For details on issue see - #2206 * Fixing lint issues. * chore: add session pool options for multiplexed session. * Update google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPoolOptions.java Co-authored-by: Knut Olav Løite <koloite@gmail.com> * Update google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPoolOptions.java Co-authored-by: Knut Olav Løite <koloite@gmail.com> * fix: comments. * chore: lint fix. --------- Co-authored-by: Knut Olav Løite <koloite@gmail.com>
1 parent 2498461 commit d970a2c

File tree

2 files changed

+130
-2
lines changed

2 files changed

+130
-2
lines changed

google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPoolOptions.java

+72-2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ public class SessionPoolOptions {
6969
/** Property for allowing mocking of session maintenance clock. */
7070
private final Clock poolMaintainerClock;
7171

72+
private final Duration waitForMultiplexedSession;
73+
private final boolean useMultiplexedSession;
74+
private final Duration multiplexedSessionMaintenanceDuration;
75+
7276
private SessionPoolOptions(Builder builder) {
7377
// minSessions > maxSessions is only possible if the user has only set a value for maxSessions.
7478
// 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) {
9397
this.randomizePositionQPSThreshold = builder.randomizePositionQPSThreshold;
9498
this.inactiveTransactionRemovalOptions = builder.inactiveTransactionRemovalOptions;
9599
this.poolMaintainerClock = builder.poolMaintainerClock;
100+
this.useMultiplexedSession = builder.useMultiplexedSession;
101+
this.multiplexedSessionMaintenanceDuration = builder.multiplexedSessionMaintenanceDuration;
102+
this.waitForMultiplexedSession = builder.waitForMultiplexedSession;
96103
}
97104

98105
@Override
@@ -123,7 +130,11 @@ public boolean equals(Object o) {
123130
&& Objects.equals(this.randomizePositionQPSThreshold, other.randomizePositionQPSThreshold)
124131
&& Objects.equals(
125132
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);
127138
}
128139

129140
@Override
@@ -148,7 +159,10 @@ public int hashCode() {
148159
this.releaseToPosition,
149160
this.randomizePositionQPSThreshold,
150161
this.inactiveTransactionRemovalOptions,
151-
this.poolMaintainerClock);
162+
this.poolMaintainerClock,
163+
this.useMultiplexedSession,
164+
this.multiplexedSessionMaintenanceDuration,
165+
this.waitForMultiplexedSession);
152166
}
153167

154168
public Builder toBuilder() {
@@ -271,6 +285,18 @@ long getRandomizePositionQPSThreshold() {
271285
return randomizePositionQPSThreshold;
272286
}
273287

288+
boolean getUseMultiplexedSession() {
289+
return useMultiplexedSession;
290+
}
291+
292+
Duration getMultiplexedSessionMaintenanceDuration() {
293+
return multiplexedSessionMaintenanceDuration;
294+
}
295+
296+
Duration getWaitForMultiplexedSession() {
297+
return waitForMultiplexedSession;
298+
}
299+
274300
public static Builder newBuilder() {
275301
return new Builder();
276302
}
@@ -467,6 +493,9 @@ public static class Builder {
467493
*/
468494
private long randomizePositionQPSThreshold = 0L;
469495

496+
private boolean useMultiplexedSession = false;
497+
private Duration multiplexedSessionMaintenanceDuration = Duration.ofDays(7);
498+
private Duration waitForMultiplexedSession = Duration.ofSeconds(10);
470499
private Clock poolMaintainerClock;
471500

472501
private static Position getReleaseToPositionFromSystemProperty() {
@@ -669,6 +698,47 @@ Builder setPoolMaintainerClock(Clock poolMaintainerClock) {
669698
return this;
670699
}
671700

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+
672742
/**
673743
* Sets whether the client should automatically execute a background query to detect the dialect
674744
* that is used by the database or not. Set this option to true if you do not know what the

google-cloud-spanner/src/test/java/com/google/cloud/spanner/SessionPoolOptionsTest.java

+58
Original file line numberDiff line numberDiff line change
@@ -246,4 +246,62 @@ public void testRandomizePositionQPSThreshold() {
246246
IllegalArgumentException.class,
247247
() -> SessionPoolOptions.newBuilder().setRandomizePositionQPSThreshold(-1L));
248248
}
249+
250+
@Test
251+
public void testUseMultiplexedSession() {
252+
assertEquals(false, SessionPoolOptions.newBuilder().build().getUseMultiplexedSession());
253+
assertEquals(
254+
true,
255+
SessionPoolOptions.newBuilder()
256+
.setUseMultiplexedSession(true)
257+
.build()
258+
.getUseMultiplexedSession());
259+
assertEquals(
260+
false,
261+
SessionPoolOptions.newBuilder()
262+
.setUseMultiplexedSession(true)
263+
.setUseMultiplexedSession(false)
264+
.build()
265+
.getUseMultiplexedSession());
266+
}
267+
268+
@Test
269+
public void testMultiplexedSessionMaintenanceDuration() {
270+
assertEquals(
271+
Duration.ofDays(7),
272+
SessionPoolOptions.newBuilder().build().getMultiplexedSessionMaintenanceDuration());
273+
assertEquals(
274+
Duration.ofDays(2),
275+
SessionPoolOptions.newBuilder()
276+
.setMultiplexedSessionMaintenanceDuration(Duration.ofDays(2))
277+
.build()
278+
.getMultiplexedSessionMaintenanceDuration());
279+
assertEquals(
280+
Duration.ofDays(10),
281+
SessionPoolOptions.newBuilder()
282+
.setMultiplexedSessionMaintenanceDuration(Duration.ofDays(2))
283+
.setMultiplexedSessionMaintenanceDuration(Duration.ofDays(10))
284+
.build()
285+
.getMultiplexedSessionMaintenanceDuration());
286+
}
287+
288+
@Test
289+
public void testWaitForMultiplexedSession() {
290+
assertEquals(
291+
Duration.ofSeconds(10),
292+
SessionPoolOptions.newBuilder().build().getWaitForMultiplexedSession());
293+
assertEquals(
294+
Duration.ofSeconds(20),
295+
SessionPoolOptions.newBuilder()
296+
.setWaitForMultiplexedSession(Duration.ofSeconds(20))
297+
.build()
298+
.getWaitForMultiplexedSession());
299+
assertEquals(
300+
Duration.ofSeconds(10),
301+
SessionPoolOptions.newBuilder()
302+
.setWaitForMultiplexedSession(Duration.ofSeconds(2))
303+
.setWaitForMultiplexedSession(Duration.ofSeconds(10))
304+
.build()
305+
.getWaitForMultiplexedSession());
306+
}
249307
}

0 commit comments

Comments
 (0)