Skip to content

Commit

Permalink
Raise availability guard first in LocalDatabase#stop()
Browse files Browse the repository at this point in the history
`LocalDatabase` raises the availability guard when it is stopped. It used to do
it after the datasource manager is stopped which could lead to transactions
starting when datasource is being stopped.

This commit makes `LocalDatabase` raise the guard as the first step
during stop.
  • Loading branch information
lutovich committed Feb 20, 2017
1 parent d245e96 commit 4f03415
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 3 deletions.
Expand Up @@ -236,11 +236,10 @@ public TransactionCommitProcess getCommitProcess()
private synchronized void stopWithRequirement( AvailabilityRequirement requirement ) throws Throwable
{
log.info( "Stopping, reason: " + requirement.description() );
raiseAvailabilityGuard( requirement );
databaseHealth = null;
localCommit = null;
dataSourceManager.stop();

raiseAvailabilityGuard( requirement );
}

private void raiseAvailabilityGuard( AvailabilityRequirement requirement )
Expand Down
Expand Up @@ -20,6 +20,7 @@
package org.neo4j.causalclustering.catchup.storecopy;

import org.junit.Test;
import org.mockito.InOrder;

import java.io.File;
import java.time.Clock;
Expand All @@ -37,8 +38,11 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.RETURNS_MOCKS;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;

public class LocalDatabaseTest
{
Expand Down Expand Up @@ -98,9 +102,45 @@ public void availabilityGuardRaisedOnStopForStoreCopy() throws Throwable
assertDatabaseIsStoppedForStoreCopyAndUnavailable( guard );
}

@Test
public void availabilityGuardRaisedBeforeDataSourceManagerIsStopped() throws Throwable
{
AvailabilityGuard guard = mock( AvailabilityGuard.class );
DataSourceManager dataSourceManager = mock( DataSourceManager.class );

LocalDatabase localDatabase = newLocalDatabase( guard, dataSourceManager );
localDatabase.stop();

InOrder inOrder = inOrder( guard, dataSourceManager );
// guard should be raised twice - once during construction and once during stop
inOrder.verify( guard, times( 2 ) ).require( any() );
inOrder.verify( dataSourceManager ).stop();
}

@Test
public void availabilityGuardRaisedBeforeDataSourceManagerIsStoppedForStoreCopy() throws Throwable
{
AvailabilityGuard guard = mock( AvailabilityGuard.class );
DataSourceManager dataSourceManager = mock( DataSourceManager.class );

LocalDatabase localDatabase = newLocalDatabase( guard, dataSourceManager );
localDatabase.stopForStoreCopy();

InOrder inOrder = inOrder( guard, dataSourceManager );
// guard should be raised twice - once during construction and once during stop
inOrder.verify( guard, times( 2 ) ).require( any() );
inOrder.verify( dataSourceManager ).stop();
}

private static LocalDatabase newLocalDatabase( AvailabilityGuard availabilityGuard )
{
return new LocalDatabase( new File( "." ), mock( StoreFiles.class ), mock( DataSourceManager.class ),
return newLocalDatabase( availabilityGuard, mock( DataSourceManager.class ) );
}

private static LocalDatabase newLocalDatabase( AvailabilityGuard availabilityGuard,
DataSourceManager dataSourceManager )
{
return new LocalDatabase( new File( "." ), mock( StoreFiles.class ), dataSourceManager,
mock( PageCache.class, RETURNS_MOCKS ), mock( FileSystemAbstraction.class ),
() -> mock( DatabaseHealth.class ), availabilityGuard, NullLogProvider.getInstance() );
}
Expand Down

0 comments on commit 4f03415

Please sign in to comment.