NebulaGraph Java Client  release-3.8
NebulaPool.java
1 /* Copyright (c) 2020 vesoft inc. All rights reserved.
2  *
3  * This source code is licensed under Apache 2.0 License.
4  */
5 
6 package com.vesoft.nebula.client.graph.net;
7 
8 import com.vesoft.nebula.client.graph.NebulaPoolConfig;
9 import com.vesoft.nebula.client.graph.data.HostAddress;
10 import com.vesoft.nebula.client.graph.exception.AuthFailedException;
11 import com.vesoft.nebula.client.graph.exception.ClientServerIncompatibleException;
12 import com.vesoft.nebula.client.graph.exception.IOErrorException;
13 import com.vesoft.nebula.client.graph.exception.InvalidConfigException;
14 import com.vesoft.nebula.client.graph.exception.NotValidConnectionException;
15 import java.io.Serializable;
16 import java.net.UnknownHostException;
17 import java.util.List;
18 import java.util.concurrent.atomic.AtomicBoolean;
19 import org.apache.commons.pool2.impl.AbandonedConfig;
20 import org.apache.commons.pool2.impl.BaseObjectPoolConfig;
21 import org.apache.commons.pool2.impl.GenericObjectPool;
22 import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25 
26 public class NebulaPool implements Serializable {
27 
28  private static final long serialVersionUID = 6226487268001127885L;
29 
30  private GenericObjectPool<SyncConnection> objectPool = null;
31  private LoadBalancer loadBalancer;
32  private final Logger log = LoggerFactory.getLogger(this.getClass());
33  // the wait time to get idle connection, unit ms
34  private int waitTime = 0;
35  private AtomicBoolean hasInit = new AtomicBoolean(false);
36  private AtomicBoolean isClosed = new AtomicBoolean(false);
37 
38  private void checkConfig(NebulaPoolConfig config) {
39  if (config.getIdleTime() < 0) {
40  throw new InvalidConfigException(
41  "Config idleTime:" + config.getIdleTime() + " is illegal");
42  }
43 
44  if (config.getMaxConnSize() <= 0) {
45  throw new InvalidConfigException(
46  "Config maxConnSize:" + config.getMaxConnSize() + " is illegal");
47  }
48 
49  if (config.getMinConnSize() < 0 || config.getMinConnSize() > config.getMaxConnSize()) {
50  throw new InvalidConfigException(
51  "Config minConnSize:" + config.getMinConnSize() + " is illegal");
52  }
53 
54  if (config.getTimeout() < 0) {
55  throw new InvalidConfigException(
56  "Config timeout:" + config.getTimeout() + " is illegal");
57  }
58 
59  if (config.getWaitTime() < 0) {
60  throw new InvalidConfigException(
61  "Config waitTime:" + config.getWaitTime() + " is illegal");
62  }
63 
64  if (config.getMinClusterHealthRate() < 0) {
65  throw new InvalidConfigException(
66  "Config minClusterHealthRate:" + config.getMinClusterHealthRate()
67  + " is illegal");
68  }
69  }
70 
78  public boolean init(List<HostAddress> addresses, NebulaPoolConfig config)
79  throws UnknownHostException, InvalidConfigException {
80  checkInit();
81  hasInit.set(true);
82  checkConfig(config);
83  this.waitTime = config.getWaitTime();
84  this.loadBalancer = config.isEnableSsl()
85  ? new RoundRobinLoadBalancer(addresses, config.getTimeout(), config.getSslParam(),
86  config.getMinClusterHealthRate(), config.isUseHttp2(), config.getCustomHeaders())
87  : new RoundRobinLoadBalancer(addresses, config.getTimeout(),
88  config.getMinClusterHealthRate(), config.isUseHttp2(), config.getCustomHeaders());
89  ConnObjectPool objectPool = new ConnObjectPool(this.loadBalancer, config);
90  this.objectPool = new GenericObjectPool<>(objectPool);
91  GenericObjectPoolConfig objConfig = new GenericObjectPoolConfig();
92  objConfig.setMinIdle(config.getMinConnSize());
93  objConfig.setMaxIdle(config.getMaxConnSize());
94  objConfig.setMaxTotal(config.getMaxConnSize());
95  objConfig.setTestOnBorrow(true);
96  objConfig.setTestOnReturn(true);
97  objConfig.setTestOnCreate(true);
98  objConfig.setTestWhileIdle(true);
99  objConfig.setTimeBetweenEvictionRunsMillis(config.getIntervalIdle() <= 0
100  ? BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS
101  : config.getIntervalIdle());
102  objConfig.setSoftMinEvictableIdleTimeMillis(config.getIdleTime() <= 0
103  ? BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS
104  : config.getIdleTime());
105  this.objectPool.setConfig(objConfig);
106 
107  AbandonedConfig abandonedConfig = new AbandonedConfig();
108  abandonedConfig.setRemoveAbandonedOnBorrow(true);
109  this.objectPool.setAbandonedConfig(abandonedConfig);
110  return objectPool.init();
111  }
112 
116  public void close() {
117  if (isClosed.get()) {
118  return;
119  }
120  isClosed.set(true);
121  this.loadBalancer.close();
122  this.objectPool.close();
123  }
124 
136  public Session getSession(String userName, String password, boolean reconnect)
139  checkNoInitAndClosed();
140  SyncConnection connection = null;
141  try {
142  connection = getConnection();
143  AuthResult authResult = connection.authenticate(userName, password);
144  return new Session(connection, authResult, this, reconnect);
145  } catch (Exception e) {
146  // if get the connection succeeded, but authenticate failed,
147  // needs to return connection to pool
148  if (connection != null) {
149  setInvalidateConnection(connection);
150  }
151  throw e;
152  }
153  }
154 
160  public int getActiveConnNum() {
161  checkNoInitAndClosed();
162  return objectPool.getNumActive();
163  }
164 
170  public int getIdleConnNum() {
171  checkNoInitAndClosed();
172  return objectPool.getNumIdle();
173  }
174 
180  public int getWaitersNum() {
181  checkNoInitAndClosed();
182  return objectPool.getNumWaiters();
183  }
184 
189  protected void updateServerStatus() {
190  checkNoInitAndClosed();
191  if (objectPool.getFactory() instanceof ConnObjectPool) {
192  ((ConnObjectPool) objectPool.getFactory()).updateServerStatus();
193  }
194  }
195 
201  protected void setInvalidateConnection(SyncConnection connection) {
202  checkNoInitAndClosed();
203  try {
204  objectPool.invalidateObject(connection);
205  } catch (Exception e) {
206  log.error("Set invalidate object failed");
207  }
208  }
209 
215  protected void returnConnection(SyncConnection connection) {
216  checkNoInitAndClosed();
217  objectPool.returnObject(connection);
218  }
219 
220  protected SyncConnection getConnection() throws NotValidConnectionException {
221  checkNoInitAndClosed();
222  try {
223  return objectPool.borrowObject(waitTime);
224  } catch (Exception e) {
225  throw new NotValidConnectionException(e.getMessage());
226  }
227  }
228 
229  private void checkNoInit() throws RuntimeException {
230  if (!hasInit.get()) {
231  throw new RuntimeException(
232  "The pool has not been initialized, please initialize it first.");
233  }
234  }
235 
236  private void checkInit() throws RuntimeException {
237  if (hasInit.get()) {
238  throw new RuntimeException(
239  "The pool has already been initialized. "
240  + "Please do not initialize the pool repeatedly.");
241  }
242  }
243 
244  private void checkNoInitAndClosed() throws RuntimeException {
245  checkNoInit();
246  checkClosed();
247  }
248 
249  private void checkClosed() throws RuntimeException {
250  if (isClosed.get()) {
251  throw new RuntimeException("The pool has closed. Couldn't use again.");
252  }
253  }
254 }
int getActiveConnNum()
Get the number of connections was used by users.
int getIdleConnNum()
Get the number of free connections in the pool.
void updateServerStatus()
Update the services' status when the connection is broken, it is called by Session and NebulaPool.
void setInvalidateConnection(SyncConnection connection)
Set the connection is invalidate, and the object pool will destroy it.
Session getSession(String userName, String password, boolean reconnect)
get a session from the NebulaPool
int getWaitersNum()
Get the number of waits in a waiting get connection.
void close()
close the pool, all connections will be closed
boolean init(List< HostAddress > addresses, NebulaPoolConfig config)
Definition: NebulaPool.java:78
void returnConnection(SyncConnection connection)
Return the connection to object pool.
The Session is an object that operates with nebula-graph.
Definition: Session.java:53