@Override public void maintenance() { bufferingIdGeneratorFactory.maintenance(); }
@Test void createContextWithProvidedReusabilityCheck() { IdReuseEligibility reuseEligibility = mock( IdReuseEligibility.class ); IdContextFactory contextFactory = IdContextFactoryBuilder.of( fs, jobScheduler ).withIdReuseEligibility( reuseEligibility ).build(); DatabaseIdContext idContext = contextFactory.createIdContext( "database" ); IdGeneratorFactory bufferedGeneratorFactory = idContext.getIdGeneratorFactory(); assertThat( bufferedGeneratorFactory, instanceOf( BufferingIdGeneratorFactory.class ) ); BufferingIdGeneratorFactory bufferedFactory = (BufferingIdGeneratorFactory) bufferedGeneratorFactory; KernelTransactionsSnapshot snapshot = mock( KernelTransactionsSnapshot.class ); when( snapshot.allClosed() ).thenReturn( true ); bufferedFactory.initialize( () -> snapshot ); try ( IdGenerator idGenerator = bufferedFactory.open( testDirectory.file( "a" ), IdType.PROPERTY, () -> 100, 100 ) ) { idGenerator.freeId( 15 ); bufferedFactory.maintenance(); verify( reuseEligibility ).isEligible( snapshot ); } }
@Test public void shouldDelayFreeingOfAggressivelyReusedIds() { // GIVEN MockedIdGeneratorFactory actual = new MockedIdGeneratorFactory(); ControllableSnapshotSupplier boundaries = new ControllableSnapshotSupplier(); BufferingIdGeneratorFactory bufferingIdGeneratorFactory = new BufferingIdGeneratorFactory( actual, IdReuseEligibility.ALWAYS, new CommunityIdTypeConfigurationProvider() ); bufferingIdGeneratorFactory.initialize( boundaries ); IdGenerator idGenerator = bufferingIdGeneratorFactory.open( new File( "doesnt-matter" ), 10, IdType.STRING_BLOCK, () -> 0L, Integer.MAX_VALUE ); // WHEN idGenerator.freeId( 7 ); verifyNoMoreInteractions( actual.get( IdType.STRING_BLOCK ) ); // after some maintenance and transaction still not closed bufferingIdGeneratorFactory.maintenance(); verifyNoMoreInteractions( actual.get( IdType.STRING_BLOCK ) ); // although after transactions have all closed boundaries.setMostRecentlyReturnedSnapshotToAllClosed(); bufferingIdGeneratorFactory.maintenance(); // THEN verify( actual.get( IdType.STRING_BLOCK ) ).freeId( 7 ); }
@Test public void shouldDelayFreeingOfAggressivelyReusedIdsConsideringTimeAsWell() { // GIVEN MockedIdGeneratorFactory actual = new MockedIdGeneratorFactory(); final FakeClock clock = Clocks.fakeClock(); final long safeZone = MINUTES.toMillis( 1 ); ControllableSnapshotSupplier boundaries = new ControllableSnapshotSupplier(); BufferingIdGeneratorFactory bufferingIdGeneratorFactory = new BufferingIdGeneratorFactory( actual, t -> clock.millis() - t.snapshotTime() >= safeZone, new CommunityIdTypeConfigurationProvider() ); bufferingIdGeneratorFactory.initialize( boundaries ); IdGenerator idGenerator = bufferingIdGeneratorFactory.open( new File( "doesnt-matter" ), 10, IdType.STRING_BLOCK, () -> 0L, Integer.MAX_VALUE ); // WHEN idGenerator.freeId( 7 ); verifyNoMoreInteractions( actual.get( IdType.STRING_BLOCK ) ); // after some maintenance and transaction still not closed bufferingIdGeneratorFactory.maintenance(); verifyNoMoreInteractions( actual.get( IdType.STRING_BLOCK ) ); // although after transactions have all closed boundaries.setMostRecentlyReturnedSnapshotToAllClosed(); bufferingIdGeneratorFactory.maintenance(); // ... the clock would still say "nope" so no interaction verifyNoMoreInteractions( actual.get( IdType.STRING_BLOCK ) ); // then finally after time has passed as well clock.forward( 70, SECONDS ); bufferingIdGeneratorFactory.maintenance(); // THEN verify( actual.get( IdType.STRING_BLOCK ) ).freeId( 7 ); }
@Override public void maintenance() { bufferingIdGeneratorFactory.maintenance(); }