Exemplo n.º 1
0
  public PoolBagEntry(final Connection connection, final HikariPool pool) {
    this.connection = connection;
    this.parentPool = pool;
    this.creationTime = System.currentTimeMillis();
    this.poolElf = pool.poolElf;
    this.state = new AtomicInteger(STATE_NOT_IN_USE);
    this.lastAccess = ClockSource.INSTANCE.currentTime();
    this.openStatements = new FastList<>(Statement.class, 16);

    poolElf.resetPoolEntry(this);

    final long maxLifetime = pool.config.getMaxLifetime();
    final long variance = maxLifetime > 60_000 ? ThreadLocalRandom.current().nextLong(10_000) : 0;
    final long lifetime = maxLifetime - variance;
    if (lifetime > 0) {
      endOfLife =
          pool.houseKeepingExecutorService.schedule(
              new Runnable() {
                @Override
                public void run() {
                  // If we can reserve it, close it
                  if (pool.connectionBag.reserve(PoolBagEntry.this)) {
                    pool.closeConnection(PoolBagEntry.this, "(connection reached maxLifetime)");
                  } else {
                    // else the connection is "in-use" and we mark it for eviction by
                    // pool.releaseConnection() or the housekeeper
                    PoolBagEntry.this.evicted = true;
                  }
                }
              },
              lifetime,
              TimeUnit.MILLISECONDS);
    }
  }
  // @Test
  public void testConnectionCloseBlocking() throws SQLException {
    HikariConfig config = new HikariConfig();
    config.setMinimumIdle(0);
    config.setMaximumPoolSize(1);
    config.setConnectionTimeout(1500);
    config.setDataSource(new CustomMockDataSource());

    long start = ClockSource.INSTANCE.currentTime();
    try (HikariDataSource ds = new HikariDataSource(config)) {
      Connection connection = ds.getConnection();
      connection.close();

      // Hikari only checks for validity for connections with lastAccess > 1000 ms so we sleep for
      // 1001 ms to force
      // Hikari to do a connection validation which will fail and will trigger the connection to be
      // closed
      UtilityElf.quietlySleep(1100L);

      shouldFail = true;

      // on physical connection close we sleep 2 seconds
      connection = ds.getConnection();

      Assert.assertTrue(
          "Waited longer than timeout",
          (ClockSource.INSTANCE.elapsedMillis(start) < config.getConnectionTimeout()));
    } catch (SQLException e) {
      Assert.assertTrue(
          "getConnection failed because close connection took longer than timeout",
          (ClockSource.INSTANCE.elapsedMillis(start) < config.getConnectionTimeout()));
    }
  }