@Override public void close() throws IndexEntryConflictException { for ( IndexUpdater part : this ) { part.close(); } }
@Override public void close() throws IndexEntryConflictException { for ( IndexUpdater updater : this ) { updater.close(); } }
@Override public void close() throws IndexEntryConflictException { try { delegate.close(); } finally { closeCall(); } } };
@Override public void close() { try { delegate.close(); } catch ( IndexEntryConflictException conflict ) { failures.add( conflict ); } } };
@Override public void close() throws IndexEntryConflictException { try { delegate.close(); } finally { lock.readLock().unlock(); } } }
@Override public void close() throws IndexEntryConflictException { delegate.close(); storeView.incrementIndexUpdates( indexId, updates ); } }
@Override public void close() throws IndexEntryConflictException { actual.close(); } }
public void closeUpdater( DatabaseIndex<? extends IndexReader> index, IndexUpdater indexUpdater ) { scheduler.schedule( Group.INDEX_UPDATING, () -> { try { indexUpdater.close(); } catch ( IndexEntryConflictException e ) { markAsFailed( index, e ); } } ); }
@Override public void close() throws IndexEntryConflictException { AtomicReference<IndexEntryConflictException> chainedExceptions = new AtomicReference<>(); instanceSelector.close( indexUpdater -> { try { indexUpdater.close(); } catch ( IndexEntryConflictException e ) { if ( !chainedExceptions.compareAndSet( null, e ) ) { chainedExceptions.get().addSuppressed( e ); } } } ); if ( chainedExceptions.get() != null ) { throw chainedExceptions.get(); } } }
@Override public void close() { for ( Pair<IndexPopulation,IndexUpdater> pair : populationsWithUpdaters.values() ) { IndexPopulation population = pair.first(); IndexUpdater updater = pair.other(); try { updater.close(); } catch ( Throwable t ) { multipleIndexPopulator.fail( population, t ); } } populationsWithUpdaters.clear(); } }
@Test public void closeMustCloseAll() throws Exception { // when fusionIndexUpdater.close(); // then for ( IndexUpdater updater : aliveUpdaters ) { verify( updater, times( 1 ) ).close(); } }
@Test public void shouldHandleCloseWithoutCallsToProcess() throws Exception { // given IndexUpdater updater = accessor.newUpdater( ONLINE ); // when updater.close(); // then // ... should be fine }
@Test public void testPropertyUpdateFailure() throws IndexEntryConflictException, FlipFailedKernelException { IndexEntryUpdate<?> propertyUpdate = createIndexEntryUpdate( index1 ); IndexUpdater indexUpdater1 = mock( IndexUpdater.class ); IndexPopulator indexPopulator1 = createIndexPopulator( indexUpdater1 ); addPopulator( indexPopulator1, 1 ); doThrow( getPopulatorException() ).when( indexUpdater1 ).process( propertyUpdate ); IndexUpdater multipleIndexUpdater = multipleIndexPopulator.newPopulatingUpdater( mock( NodePropertyAccessor.class ) ); multipleIndexUpdater.process( propertyUpdate ); verify( indexUpdater1 ).close(); checkPopulatorFailure( indexPopulator1 ); }
@Test public void testMultiplePropertyUpdateFailures() throws IndexEntryConflictException, FlipFailedKernelException { NodePropertyAccessor nodePropertyAccessor = mock( NodePropertyAccessor.class ); IndexEntryUpdate<?> update1 = add( 1, index1, "foo" ); IndexEntryUpdate<?> update2 = add( 2, index1, "bar" ); IndexUpdater updater = mock( IndexUpdater.class ); IndexPopulator populator = createIndexPopulator( updater ); addPopulator( populator, 1 ); doThrow( getPopulatorException() ).when( updater ).process( any( IndexEntryUpdate.class ) ); IndexUpdater multipleIndexUpdater = multipleIndexPopulator.newPopulatingUpdater( nodePropertyAccessor ); multipleIndexUpdater.process( update1 ); multipleIndexUpdater.process( update2 ); verify( updater ).process( update1 ); verify( updater, never() ).process( update2 ); verify( updater ).close(); checkPopulatorFailure( populator ); }
@Test public void shouldCloseAllUpdaters() throws Exception { // given indexMap.putIndexProxy( indexProxy1 ); indexMap.putIndexProxy( indexProxy2 ); IndexUpdater updater1 = updaterMap.getUpdater( schemaIndexDescriptor1.schema() ); IndexUpdater updater2 = updaterMap.getUpdater( schemaIndexDescriptor2.schema() ); // hen updaterMap.close(); // then verify( updater1 ).close(); verify( updater2 ).close(); assertTrue( "updater map must be empty", updaterMap.isEmpty() ); } }
@Test public void processMustThrowAfterClose() throws Exception { // given IndexUpdater updater = accessor.newUpdater( ONLINE ); updater.close(); // then expected.expect( IllegalStateException.class ); // when updater.process( simpleUpdate() ); }
@Test public void applicationOfUpdatesShouldFlush() throws Exception { // Given when( accessor.newUpdater( any( IndexUpdateMode.class ) ) ).thenReturn( updater ); IndexingService indexing = newIndexingServiceWithMockedDependencies( populator, accessor, withData() ); life.start(); indexing.createIndexes( index.withId( 0 ) ); waitForIndexesToComeOnline( indexing, 0 ); verify( populator, timeout( 10000 ) ).close( true ); // When indexing.apply( updates( asList( add( 1, "foo" ), add( 2, "bar" ) ) ) ); // Then InOrder inOrder = inOrder( updater ); inOrder.verify( updater ).process( add( 1, "foo" ) ); inOrder.verify( updater ).process( add( 2, "bar" ) ); inOrder.verify( updater ).close(); inOrder.verifyNoMoreInteractions(); }
@Test public void shouldBringIndexOnlineAndFlipOverToIndexAccessor() throws Exception { // given when( accessor.newUpdater( any( IndexUpdateMode.class ) ) ).thenReturn(updater); IndexingService indexingService = newIndexingServiceWithMockedDependencies( populator, accessor, withData() ); life.start(); // when indexingService.createIndexes( index.withId( 0 ) ); IndexProxy proxy = indexingService.getIndexProxy( 0 ); waitForIndexesToComeOnline( indexingService, 0 ); verify( populator, timeout( 10000 ) ).close( true ); try ( IndexUpdater updater = proxy.newUpdater( IndexUpdateMode.ONLINE ) ) { updater.process( add( 10, "foo" ) ); } // then assertEquals( InternalIndexState.ONLINE, proxy.getState() ); InOrder order = inOrder( populator, accessor, updater); order.verify( populator ).create(); order.verify( populator ).close( true ); order.verify( accessor ).newUpdater( IndexUpdateMode.ONLINE_IDEMPOTENT ); order.verify( updater ).process( add( 10, "foo" ) ); order.verify( updater ).close(); }
@Test public void shouldNotRejectDuplicateEntryOnSameNodeIdAfterUsingPopulatingUpdater() throws Exception { // given populator = newPopulator(); when( nodePropertyAccessor.getNodePropertyValue( 1, PROPERTY_KEY_ID ) ).thenReturn( Values.of( "value1" ) ); IndexUpdater updater = populator.newPopulatingUpdater( nodePropertyAccessor ); updater.process( add( 1, schemaDescriptor, "value1" ) ); updater.process( change( 1, schemaDescriptor, "value1", "value1" ) ); updater.close(); addUpdate( populator, 2, "value2" ); addUpdate( populator, 3, "value3" ); // when populator.verifyDeferredConstraints( nodePropertyAccessor ); populator.close( true ); // then assertEquals( asList( 1L ), getAllNodes( getDirectory(), "value1" ) ); assertEquals( asList( 2L ), getAllNodes( getDirectory(), "value2" ) ); assertEquals( asList( 3L ), getAllNodes( getDirectory(), "value3" ) ); }
@Test public void updaterMustThrowIfProcessAfterClose() throws Exception { // given populator.create(); IndexUpdater updater = populator.newPopulatingUpdater( null_property_accessor ); // when updater.close(); // then try { updater.process( valueCreatorUtil.add( 1, Values.of( Long.MAX_VALUE ) ) ); fail( "Expected process to throw on closed updater" ); } catch ( IllegalStateException e ) { // good } populator.close( true ); }