nl.topicus.jdbc.shaded.com.google.cloud.spanner.SessionPoolOptions Maven / Gradle / Ivy
Show all versions of spanner-jdbc Show documentation
/*
* Copyright 2017 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package nl.topicus.jdbc.shaded.com.google.cloud.spanner;
import nl.topicus.jdbc.shaded.com.google.common.base.Preconditions;
/** Options for the session pool used by {@code DatabaseClient}. */
public class SessionPoolOptions {
// Default number of channels * 100.
private static final int DEFAULT_MAX_SESSIONS = 400;
private static final ActionOnExhaustion DEFAULT_ACTION = ActionOnExhaustion.BLOCK;
private final int minSessions;
private final int maxSessions;
private final int maxIdleSessions;
private final float writeSessionsFraction;
private final ActionOnExhaustion actionOnExhaustion;
private final int keepAliveIntervalMinutes;
private SessionPoolOptions(Builder builder) {
this.minSessions = builder.minSessions;
this.maxSessions = builder.maxSessions;
this.maxIdleSessions = builder.maxIdleSessions;
this.writeSessionsFraction = builder.writeSessionsFraction;
this.actionOnExhaustion = builder.actionOnExhaustion;
this.keepAliveIntervalMinutes = builder.keepAliveIntervalMinutes;
}
public int getMinSessions() {
return minSessions;
}
public int getMaxSessions() {
return maxSessions;
}
public int getMaxIdleSessions() {
return maxIdleSessions;
}
public float getWriteSessionsFraction() {
return writeSessionsFraction;
}
public int getKeepAliveIntervalMinutes() {
return keepAliveIntervalMinutes;
}
public boolean isFailIfPoolExhausted() {
return actionOnExhaustion == ActionOnExhaustion.FAIL;
}
public boolean isBlockIfPoolExhausted() {
return actionOnExhaustion == ActionOnExhaustion.BLOCK;
}
public static Builder newBuilder() {
return new Builder();
}
private static enum ActionOnExhaustion {
BLOCK,
FAIL,
}
/** Builder for creating SessionPoolOptions. */
public static class Builder {
private int minSessions;
private int maxSessions = DEFAULT_MAX_SESSIONS;
private int maxIdleSessions;
private float writeSessionsFraction = 0.2f;
private ActionOnExhaustion actionOnExhaustion = DEFAULT_ACTION;
private int keepAliveIntervalMinutes = 30;
/**
* Minimum number of sessions that this pool will always maintain. These will be created eagerly
* in parallel. Defaults to 0.
*/
public Builder setMinSessions(int minSessions) {
this.minSessions = minSessions;
return this;
}
/**
* Maximum number of sessions that this pool will have. If current numbers of sessions in the
* pool is less than this and they are all busy, then a new session will be created for any new
* operation. If current number of in use sessions is same as this and a new request comes, pool
* can either block or fail. Defaults to 2000.
*/
public Builder setMaxSessions(int maxSessions) {
this.maxSessions = maxSessions;
return this;
}
/**
* Maximum number of idle sessions that this pool will maintain. Pool will close any sessions
* beyond this but making sure to always have at least as many sessions as specified by {@link
* #setMinSessions}. To determine how many sessions are idle we look at maximum number of
* sessions used concurrently over a window of time. Any sessions beyond that are idle. Defaults
* to 0.
*/
public Builder setMaxIdleSessions(int maxIdleSessions) {
this.maxIdleSessions = maxIdleSessions;
return this;
}
/**
* How frequently to keep alive idle sessions. This should be less than 60 since an idle session
* is automatically closed after 60 minutes. Sessions will be kept alive by sending a dummy
* query "Select 1". Default value is 30 minutes.
*/
public Builder setKeepAliveIntervalMinutes(int intervalMinutes) {
this.keepAliveIntervalMinutes = intervalMinutes;
return this;
}
/**
* If all sessions are in use and and {@code maxSessions} has been reached, fail the request by
* throwing a {@link SpannerException} with the error code {@code RESOURCE_EXHAUSTED}. Default
* behavior is to block the request.
*/
public Builder setFailIfPoolExhausted() {
this.actionOnExhaustion = ActionOnExhaustion.FAIL;
return this;
}
/**
* If all sessions are in use and there is no more room for creating new sessions, block for a
* session to become available. Default behavior is same.
*/
public Builder setBlockIfPoolExhausted() {
this.actionOnExhaustion = ActionOnExhaustion.BLOCK;
return this;
}
/**
* Fraction of sessions to be kept prepared for write transactions. This is an optimisation to
* avoid the cost of sending a BeginTransaction() rpc. If all such sessions are in use and a
* write request comes, we will make the BeginTransaction() rpc inline. It must be between 0 and
* 1(inclusive).
*
* Default value is 0.2.
*/
public Builder setWriteSessionsFraction(float writeSessionsFraction) {
this.writeSessionsFraction = writeSessionsFraction;
return this;
}
/** Build a SessionPoolOption object */
public SessionPoolOptions build() {
validate();
return new SessionPoolOptions(this);
}
private void validate() {
Preconditions.checkArgument(maxSessions >= minSessions,
"Min sessions(%s) must be <= max sessions(%s)", minSessions, maxSessions);
Preconditions.checkArgument(
keepAliveIntervalMinutes < 60, "Keep alive interval should be less than" + "60 minutes");
Preconditions.checkArgument(
writeSessionsFraction >= 0 && writeSessionsFraction <= 1,
"Fraction of write sessions must be between 0 and 1 (inclusive)");
}
}
}