Skip to content

Commit

Permalink
Close connections during CRaC snapshotting
Browse files Browse the repository at this point in the history
Signed-off-by: Radim Vansa <[email protected]>
  • Loading branch information
rvansa committed Sep 5, 2024
1 parent 73871fc commit 5ddcb64
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 2 deletions.
5 changes: 5 additions & 0 deletions agroal-pool/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
<artifactId>agroal-api</artifactId>
<version>${forked.version}</version>
</dependency>
<dependency>
<groupId>org.crac</groupId>
<artifactId>crac</artifactId>
<version>${version.org.crac}</version>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
21 changes: 19 additions & 2 deletions agroal-pool/src/main/java/io/agroal/pool/ConnectionPool.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
import java.util.concurrent.atomic.LongAdder;
import java.util.function.Function;

import org.crac.Context;
import org.crac.Core;
import org.crac.Resource;

import static io.agroal.api.AgroalDataSource.FlushMode.GRACEFUL;
import static io.agroal.api.AgroalDataSource.FlushMode.LEAK;
import static io.agroal.api.configuration.AgroalConnectionPoolConfiguration.MultipleAcquisitionAction.OFF;
Expand Down Expand Up @@ -74,7 +78,7 @@
/**
* @author <a href="[email protected]">Luis Barreiro</a>
*/
public final class ConnectionPool implements Pool {
public final class ConnectionPool implements Pool, Resource {

private static final AtomicInteger HOUSEKEEP_COUNT = new AtomicInteger();

Expand All @@ -85,7 +89,7 @@ public final class ConnectionPool implements Pool {

private final AgroalSynchronizer synchronizer;
private final ConnectionFactory connectionFactory;
private final PriorityScheduledExecutor housekeepingExecutor;
private PriorityScheduledExecutor housekeepingExecutor;
private final TransactionIntegration transactionIntegration;

private final boolean borrowValidationEnabled;
Expand Down Expand Up @@ -118,6 +122,8 @@ public ConnectionPool(AgroalConnectionPoolConfiguration configuration, AgroalDat
leakEnabled = !configuration.leakTimeout().isZero();
validationEnabled = !configuration.validationTimeout().isZero();
reapEnabled = !configuration.reapTimeout().isZero();

Core.getGlobalContext().register(this);
}

public void init() {
Expand Down Expand Up @@ -556,6 +562,17 @@ public boolean isHealthy(boolean newConnection) throws SQLException {
return performValidation( healthHandler, CHECKED_IN );
}

@Override
public void beforeCheckpoint(Context<? extends Resource> context) throws Exception {
close();
}

@Override
public void afterRestore(Context<? extends Resource> context) throws Exception {
housekeepingExecutor = new PriorityScheduledExecutor( 1, "agroal-" + HOUSEKEEP_COUNT.incrementAndGet(), listeners );
init();
}

// --- create //

private final class CreateConnectionTask implements Callable<ConnectionHandler> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package io.agroal.test.basic;

import io.agroal.api.AgroalDataSource;
import io.agroal.api.configuration.supplier.AgroalDataSourceConfigurationSupplier;
import io.agroal.pool.DataSource;
import io.agroal.pool.Pool;
import io.agroal.test.MockConnection;
import org.crac.Resource;
import org.junit.jupiter.api.*;

import java.lang.reflect.Field;
import java.sql.Connection;

import static io.agroal.test.AgroalTestGroup.FUNCTIONAL;
import static io.agroal.test.MockDriver.deregisterMockDriver;
import static io.agroal.test.MockDriver.registerMockDriver;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertTrue;

@Tag( FUNCTIONAL )
public class CheckpointTests {
@BeforeAll
static void setupMockDriver() {
registerMockDriver( FakeConnection.class );
}

@AfterAll
static void teardown() {
deregisterMockDriver();
}

// --- //

@Test
@DisplayName( "ConnectionPool C/R" )
void checkpointRestoreTest() throws Exception {
try ( AgroalDataSource dataSource = AgroalDataSource.from( new AgroalDataSourceConfigurationSupplier().connectionPoolConfiguration(cp -> cp.maxSize( 1 ) ) ) ) {
Connection connection = dataSource.getConnection();

assertFalse( connection.isClosed(), "Expected open connection, but it's closed" );

Field cpField = DataSource.class.getDeclaredField("connectionPool");
cpField.setAccessible(true);
Pool pool = (Pool) cpField.get(dataSource);
assertInstanceOf(Resource.class, pool);
Resource poolResource = (Resource) pool;

poolResource.beforeCheckpoint(null);

assertTrue( connection.isClosed(), "Expected closed connection, but it's open" );

poolResource.afterRestore(null);

Connection another = dataSource.getConnection();
assertFalse( another.isClosed(), "Expected open connection, but it's closed" );
}
}

public static class FakeConnection implements MockConnection {
private boolean closed;

@Override
public void close() {
closed = true;
}

@Override
public boolean isClosed() {
return closed;
}
}

}
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
<version.eu.somatik.serviceloader-maven-plugin>1.4.0</version.eu.somatik.serviceloader-maven-plugin>
<version.org.apache.maven.plugins.maven-surefire-plugin>3.3.1</version.org.apache.maven.plugins.maven-surefire-plugin>
<version.org.netbeans.tools.sigtest-maven-plugin>1.6</version.org.netbeans.tools.sigtest-maven-plugin>
<version.org.crac>1.5.0</version.org.crac>
</properties>
<build>
<plugins>
Expand Down

0 comments on commit 5ddcb64

Please sign in to comment.