Search in sources :

Example 6 with PooledSessionFuture

use of com.google.cloud.spanner.SessionPool.PooledSessionFuture in project java-spanner by googleapis.

the class SessionPoolTest method poolClosureFailsPendingWriteWaiters.

@Test
public void poolClosureFailsPendingWriteWaiters() throws Exception {
    final CountDownLatch insideCreation = new CountDownLatch(1);
    final CountDownLatch releaseCreation = new CountDownLatch(1);
    final SessionImpl session1 = mockSession();
    final SessionImpl session2 = mockSession();
    doAnswer(invocation -> {
        executor.submit(() -> {
            SessionConsumerImpl consumer = invocation.getArgument(2, SessionConsumerImpl.class);
            consumer.onSessionReady(session1);
        });
        return null;
    }).doAnswer(invocation -> {
        executor.submit(() -> {
            insideCreation.countDown();
            releaseCreation.await();
            SessionConsumerImpl consumer = invocation.getArgument(2, SessionConsumerImpl.class);
            consumer.onSessionReady(session2);
            return null;
        });
        return null;
    }).when(sessionClient).asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class));
    pool = createPool();
    PooledSessionFuture leakedSession = pool.getSession();
    // Suppress expected leakedSession warning.
    leakedSession.clearLeakedException();
    AtomicBoolean failed = new AtomicBoolean(false);
    CountDownLatch latch = new CountDownLatch(1);
    getSessionAsync(latch, failed);
    insideCreation.await();
    pool.closeAsync(new SpannerImpl.ClosedException());
    releaseCreation.countDown();
    latch.await();
    assertThat(failed.get()).isTrue();
}
Also used : TransactionCallable(com.google.cloud.spanner.TransactionRunner.TransactionCallable) Arrays(java.util.Arrays) ClosedException(com.google.cloud.spanner.SpannerImpl.ClosedException) QueryAnalyzeMode(com.google.cloud.spanner.ReadContext.QueryAnalyzeMode) CommitResponse(com.google.spanner.v1.CommitResponse) Timestamp(com.google.cloud.Timestamp) Clock(com.google.cloud.spanner.SessionPool.Clock) PooledSession(com.google.cloud.spanner.SessionPool.PooledSession) Mockito.doThrow(org.mockito.Mockito.doThrow) Empty(com.google.protobuf.Empty) ResultSetStats(com.google.spanner.v1.ResultSetStats) Future(java.util.concurrent.Future) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Map(java.util.Map) Assert.fail(org.junit.Assert.fail) Parameterized(org.junit.runners.Parameterized) ResultStreamConsumer(com.google.cloud.spanner.spi.v1.SpannerRpc.ResultStreamConsumer) PrintWriter(java.io.PrintWriter) PointWithFunction(com.google.cloud.spanner.MetricRegistryTestUtils.PointWithFunction) ApiFutures(com.google.api.core.ApiFutures) Collection(java.util.Collection) NUM_READ_SESSIONS(com.google.cloud.spanner.MetricRegistryConstants.NUM_READ_SESSIONS) Executors(java.util.concurrent.Executors) ByteString(com.google.protobuf.ByteString) CountDownLatch(java.util.concurrent.CountDownLatch) NUM_SESSIONS_BEING_PREPARED(com.google.cloud.spanner.MetricRegistryConstants.NUM_SESSIONS_BEING_PREPARED) List(java.util.List) LabelValue(io.opencensus.metrics.LabelValue) Mockito.atMost(org.mockito.Mockito.atMost) ExecuteSqlRequest(com.google.spanner.v1.ExecuteSqlRequest) Mockito.any(org.mockito.Mockito.any) MetricRegistry(io.opencensus.metrics.MetricRegistry) SPANNER_LABEL_KEYS_WITH_TYPE(com.google.cloud.spanner.MetricRegistryConstants.SPANNER_LABEL_KEYS_WITH_TYPE) Mockito.eq(org.mockito.Mockito.eq) Mockito.mock(org.mockito.Mockito.mock) MockitoAnnotations.initMocks(org.mockito.MockitoAnnotations.initMocks) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) Mock(org.mockito.Mock) SPANNER_LABEL_KEYS(com.google.cloud.spanner.MetricRegistryConstants.SPANNER_LABEL_KEYS) Assert.assertThrows(org.junit.Assert.assertThrows) RunWith(org.junit.runner.RunWith) Parameters(org.junit.runners.Parameterized.Parameters) SpannerRpc(com.google.cloud.spanner.spi.v1.SpannerRpc) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ArrayList(java.util.ArrayList) CommitRequest(com.google.spanner.v1.CommitRequest) PooledSessionFuture(com.google.cloud.spanner.SessionPool.PooledSessionFuture) MetricsRecord(com.google.cloud.spanner.MetricRegistryTestUtils.MetricsRecord) SessionConsumerImpl(com.google.cloud.spanner.SessionPool.SessionConsumerImpl) LinkedList(java.util.LinkedList) ExecutorService(java.util.concurrent.ExecutorService) Before(org.junit.Before) FakeMetricRegistry(com.google.cloud.spanner.MetricRegistryTestUtils.FakeMetricRegistry) Uninterruptibles(com.google.common.util.concurrent.Uninterruptibles) NUM_IN_USE_SESSIONS(com.google.cloud.spanner.MetricRegistryConstants.NUM_IN_USE_SESSIONS) Assert.assertNotNull(org.junit.Assert.assertNotNull) Parameter(org.junit.runners.Parameterized.Parameter) StringWriter(java.io.StringWriter) Assert.assertTrue(org.junit.Assert.assertTrue) Mockito.times(org.mockito.Mockito.times) Test(org.junit.Test) Mockito.when(org.mockito.Mockito.when) Truth.assertThat(com.google.common.truth.Truth.assertThat) Span(io.opencensus.trace.Span) Mockito.verify(org.mockito.Mockito.verify) RollbackRequest(com.google.spanner.v1.RollbackRequest) NUM_WRITE_SESSIONS(com.google.cloud.spanner.MetricRegistryConstants.NUM_WRITE_SESSIONS) TimeUnit(java.util.concurrent.TimeUnit) Mockito(org.mockito.Mockito) Mockito.never(org.mockito.Mockito.never) Mockito.anyInt(org.mockito.Mockito.anyInt) TransactionContextImpl(com.google.cloud.spanner.TransactionRunnerImpl.TransactionContextImpl) ExecuteBatchDmlRequest(com.google.spanner.v1.ExecuteBatchDmlRequest) Collections(java.util.Collections) Assert.assertEquals(org.junit.Assert.assertEquals) SessionConsumer(com.google.cloud.spanner.SessionClient.SessionConsumer) SessionConsumer(com.google.cloud.spanner.SessionClient.SessionConsumer) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) SessionConsumerImpl(com.google.cloud.spanner.SessionPool.SessionConsumerImpl) PooledSessionFuture(com.google.cloud.spanner.SessionPool.PooledSessionFuture) ClosedException(com.google.cloud.spanner.SpannerImpl.ClosedException) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test)

Example 7 with PooledSessionFuture

use of com.google.cloud.spanner.SessionPool.PooledSessionFuture in project java-spanner by googleapis.

the class SessionPoolTest method blockAndTimeoutOnPoolExhaustion.

@Test
public void blockAndTimeoutOnPoolExhaustion() throws Exception {
    // Create a session pool with max 1 session and a low timeout for waiting for a session.
    options = SessionPoolOptions.newBuilder().setMinSessions(minSessions).setMaxSessions(1).setInitialWaitForSessionTimeoutMillis(20L).build();
    setupMockSessionCreation();
    pool = createPool();
    // Take the only session that can be in the pool.
    PooledSessionFuture checkedOutSession = pool.getSession();
    checkedOutSession.get();
    ExecutorService executor = Executors.newFixedThreadPool(1);
    final CountDownLatch latch = new CountDownLatch(1);
    // Then try asynchronously to take another session. This attempt should time out.
    Future<Void> fut = executor.submit(() -> {
        latch.countDown();
        PooledSessionFuture session = pool.getSession();
        session.close();
        return null;
    });
    // Wait until the background thread is actually waiting for a session.
    latch.await();
    // Wait until the request has timed out.
    int waitCount = 0;
    while (pool.getNumWaiterTimeouts() == 0L && waitCount < 1000) {
        Thread.sleep(5L);
        waitCount++;
    }
    // Return the checked out session to the pool so the async request will get a session and
    // finish.
    checkedOutSession.close();
    // Verify that the async request also succeeds.
    fut.get(10L, TimeUnit.SECONDS);
    executor.shutdown();
    // Verify that the session was returned to the pool and that we can get it again.
    Session session = pool.getSession();
    assertThat(session).isNotNull();
    session.close();
    assertThat(pool.getNumWaiterTimeouts()).isAtLeast(1L);
}
Also used : PooledSessionFuture(com.google.cloud.spanner.SessionPool.PooledSessionFuture) ExecutorService(java.util.concurrent.ExecutorService) CountDownLatch(java.util.concurrent.CountDownLatch) PooledSession(com.google.cloud.spanner.SessionPool.PooledSession) Test(org.junit.Test)

Example 8 with PooledSessionFuture

use of com.google.cloud.spanner.SessionPool.PooledSessionFuture in project java-spanner by googleapis.

the class SessionPoolTest method poolClosureFailsPendingReadWaiters.

@Test
public void poolClosureFailsPendingReadWaiters() throws Exception {
    final CountDownLatch insideCreation = new CountDownLatch(1);
    final CountDownLatch releaseCreation = new CountDownLatch(1);
    final SessionImpl session1 = mockSession();
    final SessionImpl session2 = mockSession();
    doAnswer(invocation -> {
        executor.submit(() -> {
            SessionConsumerImpl consumer = invocation.getArgument(2, SessionConsumerImpl.class);
            consumer.onSessionReady(session1);
        });
        return null;
    }).doAnswer(invocation -> {
        executor.submit(() -> {
            insideCreation.countDown();
            releaseCreation.await();
            SessionConsumerImpl consumer = invocation.getArgument(2, SessionConsumerImpl.class);
            consumer.onSessionReady(session2);
            return null;
        });
        return null;
    }).when(sessionClient).asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class));
    pool = createPool();
    PooledSessionFuture leakedSession = pool.getSession();
    // Suppress expected leakedSession warning.
    leakedSession.clearLeakedException();
    AtomicBoolean failed = new AtomicBoolean(false);
    CountDownLatch latch = new CountDownLatch(1);
    getSessionAsync(latch, failed);
    insideCreation.await();
    pool.closeAsync(new SpannerImpl.ClosedException());
    releaseCreation.countDown();
    latch.await(5L, TimeUnit.SECONDS);
    assertThat(failed.get()).isTrue();
}
Also used : TransactionCallable(com.google.cloud.spanner.TransactionRunner.TransactionCallable) Arrays(java.util.Arrays) ClosedException(com.google.cloud.spanner.SpannerImpl.ClosedException) QueryAnalyzeMode(com.google.cloud.spanner.ReadContext.QueryAnalyzeMode) CommitResponse(com.google.spanner.v1.CommitResponse) Timestamp(com.google.cloud.Timestamp) Clock(com.google.cloud.spanner.SessionPool.Clock) PooledSession(com.google.cloud.spanner.SessionPool.PooledSession) Mockito.doThrow(org.mockito.Mockito.doThrow) Empty(com.google.protobuf.Empty) ResultSetStats(com.google.spanner.v1.ResultSetStats) Future(java.util.concurrent.Future) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Map(java.util.Map) Assert.fail(org.junit.Assert.fail) Parameterized(org.junit.runners.Parameterized) ResultStreamConsumer(com.google.cloud.spanner.spi.v1.SpannerRpc.ResultStreamConsumer) PrintWriter(java.io.PrintWriter) PointWithFunction(com.google.cloud.spanner.MetricRegistryTestUtils.PointWithFunction) ApiFutures(com.google.api.core.ApiFutures) Collection(java.util.Collection) NUM_READ_SESSIONS(com.google.cloud.spanner.MetricRegistryConstants.NUM_READ_SESSIONS) Executors(java.util.concurrent.Executors) ByteString(com.google.protobuf.ByteString) CountDownLatch(java.util.concurrent.CountDownLatch) NUM_SESSIONS_BEING_PREPARED(com.google.cloud.spanner.MetricRegistryConstants.NUM_SESSIONS_BEING_PREPARED) List(java.util.List) LabelValue(io.opencensus.metrics.LabelValue) Mockito.atMost(org.mockito.Mockito.atMost) ExecuteSqlRequest(com.google.spanner.v1.ExecuteSqlRequest) Mockito.any(org.mockito.Mockito.any) MetricRegistry(io.opencensus.metrics.MetricRegistry) SPANNER_LABEL_KEYS_WITH_TYPE(com.google.cloud.spanner.MetricRegistryConstants.SPANNER_LABEL_KEYS_WITH_TYPE) Mockito.eq(org.mockito.Mockito.eq) Mockito.mock(org.mockito.Mockito.mock) MockitoAnnotations.initMocks(org.mockito.MockitoAnnotations.initMocks) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) Mock(org.mockito.Mock) SPANNER_LABEL_KEYS(com.google.cloud.spanner.MetricRegistryConstants.SPANNER_LABEL_KEYS) Assert.assertThrows(org.junit.Assert.assertThrows) RunWith(org.junit.runner.RunWith) Parameters(org.junit.runners.Parameterized.Parameters) SpannerRpc(com.google.cloud.spanner.spi.v1.SpannerRpc) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ArrayList(java.util.ArrayList) CommitRequest(com.google.spanner.v1.CommitRequest) PooledSessionFuture(com.google.cloud.spanner.SessionPool.PooledSessionFuture) MetricsRecord(com.google.cloud.spanner.MetricRegistryTestUtils.MetricsRecord) SessionConsumerImpl(com.google.cloud.spanner.SessionPool.SessionConsumerImpl) LinkedList(java.util.LinkedList) ExecutorService(java.util.concurrent.ExecutorService) Before(org.junit.Before) FakeMetricRegistry(com.google.cloud.spanner.MetricRegistryTestUtils.FakeMetricRegistry) Uninterruptibles(com.google.common.util.concurrent.Uninterruptibles) NUM_IN_USE_SESSIONS(com.google.cloud.spanner.MetricRegistryConstants.NUM_IN_USE_SESSIONS) Assert.assertNotNull(org.junit.Assert.assertNotNull) Parameter(org.junit.runners.Parameterized.Parameter) StringWriter(java.io.StringWriter) Assert.assertTrue(org.junit.Assert.assertTrue) Mockito.times(org.mockito.Mockito.times) Test(org.junit.Test) Mockito.when(org.mockito.Mockito.when) Truth.assertThat(com.google.common.truth.Truth.assertThat) Span(io.opencensus.trace.Span) Mockito.verify(org.mockito.Mockito.verify) RollbackRequest(com.google.spanner.v1.RollbackRequest) NUM_WRITE_SESSIONS(com.google.cloud.spanner.MetricRegistryConstants.NUM_WRITE_SESSIONS) TimeUnit(java.util.concurrent.TimeUnit) Mockito(org.mockito.Mockito) Mockito.never(org.mockito.Mockito.never) Mockito.anyInt(org.mockito.Mockito.anyInt) TransactionContextImpl(com.google.cloud.spanner.TransactionRunnerImpl.TransactionContextImpl) ExecuteBatchDmlRequest(com.google.spanner.v1.ExecuteBatchDmlRequest) Collections(java.util.Collections) Assert.assertEquals(org.junit.Assert.assertEquals) SessionConsumer(com.google.cloud.spanner.SessionClient.SessionConsumer) SessionConsumer(com.google.cloud.spanner.SessionClient.SessionConsumer) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) SessionConsumerImpl(com.google.cloud.spanner.SessionPool.SessionConsumerImpl) PooledSessionFuture(com.google.cloud.spanner.SessionPool.PooledSessionFuture) ClosedException(com.google.cloud.spanner.SpannerImpl.ClosedException) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test)

Example 9 with PooledSessionFuture

use of com.google.cloud.spanner.SessionPool.PooledSessionFuture in project java-spanner by googleapis.

the class SessionPoolTest method idleSessionCleanup.

@Test
public void idleSessionCleanup() throws Exception {
    options = SessionPoolOptions.newBuilder().setMinSessions(1).setMaxSessions(3).setIncStep(1).setMaxIdleSessions(0).build();
    SessionImpl session1 = mockSession();
    SessionImpl session2 = mockSession();
    SessionImpl session3 = mockSession();
    final LinkedList<SessionImpl> sessions = new LinkedList<>(Arrays.asList(session1, session2, session3));
    doAnswer(invocation -> {
        executor.submit(() -> {
            SessionConsumerImpl consumer = invocation.getArgument(2, SessionConsumerImpl.class);
            consumer.onSessionReady(sessions.pop());
        });
        return null;
    }).when(sessionClient).asyncBatchCreateSessions(Mockito.eq(1), Mockito.anyBoolean(), any(SessionConsumer.class));
    for (SessionImpl session : sessions) {
        mockKeepAlive(session);
    }
    FakeClock clock = new FakeClock();
    clock.currentTimeMillis = System.currentTimeMillis();
    pool = createPool(clock);
    // Make sure pool has been initialized
    pool.getSession().close();
    runMaintenanceLoop(clock, pool, pool.poolMaintainer.numClosureCycles);
    assertThat(pool.numIdleSessionsRemoved()).isEqualTo(0L);
    PooledSessionFuture readSession1 = pool.getSession();
    PooledSessionFuture readSession2 = pool.getSession();
    PooledSessionFuture readSession3 = pool.getSession();
    // Wait until the sessions have actually been gotten in order to make sure they are in use in
    // parallel.
    readSession1.get();
    readSession2.get();
    readSession3.get();
    readSession1.close();
    readSession2.close();
    readSession3.close();
    // Now there are 3 sessions in the pool but since none of them has timed out, they will all be
    // kept in the pool.
    runMaintenanceLoop(clock, pool, pool.poolMaintainer.numClosureCycles);
    assertThat(pool.numIdleSessionsRemoved()).isEqualTo(0L);
    // Counters have now been reset
    // Use all 3 sessions sequentially
    pool.getSession().close();
    pool.getSession().close();
    pool.getSession().close();
    // Advance the time by running the maintainer. This should cause
    // one session to be kept alive and two sessions to be removed.
    long cycles = options.getRemoveInactiveSessionAfter().toMillis() / pool.poolMaintainer.loopFrequency;
    runMaintenanceLoop(clock, pool, cycles);
    // We will still close 2 sessions since at any point in time only 1 session was in use.
    assertThat(pool.numIdleSessionsRemoved()).isEqualTo(2L);
    pool.closeAsync(new SpannerImpl.ClosedException()).get(5L, TimeUnit.SECONDS);
}
Also used : SessionConsumer(com.google.cloud.spanner.SessionClient.SessionConsumer) SessionConsumerImpl(com.google.cloud.spanner.SessionPool.SessionConsumerImpl) ClosedException(com.google.cloud.spanner.SpannerImpl.ClosedException) PooledSessionFuture(com.google.cloud.spanner.SessionPool.PooledSessionFuture) LinkedList(java.util.LinkedList) Test(org.junit.Test)

Example 10 with PooledSessionFuture

use of com.google.cloud.spanner.SessionPool.PooledSessionFuture in project java-spanner by googleapis.

the class DatabaseClientImplTest method testRunAsync_usesOptions.

@Test
public void testRunAsync_usesOptions() {
    SessionPool pool = mock(SessionPool.class);
    PooledSessionFuture session = mock(PooledSessionFuture.class);
    when(pool.getSession()).thenReturn(session);
    TransactionOption option = mock(TransactionOption.class);
    DatabaseClientImpl client = new DatabaseClientImpl(pool);
    client.runAsync(option);
    verify(session).runAsync(option);
}
Also used : PooledSessionFuture(com.google.cloud.spanner.SessionPool.PooledSessionFuture) TransactionOption(com.google.cloud.spanner.Options.TransactionOption) Test(org.junit.Test)

Aggregations

PooledSessionFuture (com.google.cloud.spanner.SessionPool.PooledSessionFuture)15 Test (org.junit.Test)15 SessionConsumer (com.google.cloud.spanner.SessionClient.SessionConsumer)7 SessionConsumerImpl (com.google.cloud.spanner.SessionPool.SessionConsumerImpl)7 ClosedException (com.google.cloud.spanner.SpannerImpl.ClosedException)7 PooledSession (com.google.cloud.spanner.SessionPool.PooledSession)6 CountDownLatch (java.util.concurrent.CountDownLatch)6 FakeMetricRegistry (com.google.cloud.spanner.MetricRegistryTestUtils.FakeMetricRegistry)4 MetricsRecord (com.google.cloud.spanner.MetricRegistryTestUtils.MetricsRecord)4 PointWithFunction (com.google.cloud.spanner.MetricRegistryTestUtils.PointWithFunction)4 TransactionOption (com.google.cloud.spanner.Options.TransactionOption)4 ByteString (com.google.protobuf.ByteString)4 LabelValue (io.opencensus.metrics.LabelValue)4 LinkedList (java.util.LinkedList)4 ApiFutures (com.google.api.core.ApiFutures)3 Timestamp (com.google.cloud.Timestamp)3 NUM_IN_USE_SESSIONS (com.google.cloud.spanner.MetricRegistryConstants.NUM_IN_USE_SESSIONS)3 NUM_READ_SESSIONS (com.google.cloud.spanner.MetricRegistryConstants.NUM_READ_SESSIONS)3 NUM_SESSIONS_BEING_PREPARED (com.google.cloud.spanner.MetricRegistryConstants.NUM_SESSIONS_BEING_PREPARED)3 NUM_WRITE_SESSIONS (com.google.cloud.spanner.MetricRegistryConstants.NUM_WRITE_SESSIONS)3