public WaitDetails waitUntilWaiting() throws TimeoutException { return waitUntilWaiting( details -> true ); }
@Before public void before() { t1 = new OtherThreadExecutor<>( "T1", null ); t2 = new OtherThreadExecutor<>( "T2", null ); }
@Override protected boolean matchesSafely( OtherThreadRule rule ) { try { rule.executor.waitUntilThreadState( eitherOfStates ); return true; } catch ( TimeoutException e ) { rule.executor.printStackTrace( System.err ); return false; } }
public <RESULT> Future<RESULT> execute( OtherThreadExecutor.WorkerCommand<STATE, RESULT> cmd ) { Future<RESULT> future = executor.executeDontWait( cmd ); try { executor.awaitStartExecuting(); } catch ( InterruptedException e ) { throw new RuntimeException( "Interrupted while awaiting start of execution.", e ); } return future; }
private Future<Lock> tryToAcquireSameLockOnAnotherThread( Node resource, OtherThreadExecutor<Void> otherThread ) throws Exception { Future<Lock> future = otherThread.executeDontWait( acquireWriteLock( resource ) ); otherThread.waitUntilWaiting(); return future; }
@Test public void shouldHaveOneThreadWaitForARemoval() throws Exception { // GIVEN IdOrderingQueue queue = new SynchronizedArrayIdOrderingQueue( 5 ); queue.offer( 3 ); queue.offer( 5 ); // WHEN another thread comes in and awaits 5 OtherThreadExecutor<Void> t2 = cleanup.add( new OtherThreadExecutor<Void>( "T2", null ) ); Future<Object> await5 = t2.executeDontWait( awaitHead( queue, 5 ) ); t2.waitUntilWaiting(); // ... and head (3) gets removed queue.removeChecked( 3 ); // THEN the other thread should be OK to continue await5.get(); }
final AtomicBoolean stoppedCompleted = new AtomicBoolean(); final DoubleLatch checkPointerLatch = new DoubleLatch( 1 ); OtherThreadExecutor<Void> otherThreadExecutor = new OtherThreadExecutor<>( "scheduler stopper", null ); CheckPointer checkPointer = new CheckPointer() otherThreadExecutor.executeDontWait( (WorkerCommand<Void,Void>) state -> otherThreadExecutor.waitUntilWaiting( details -> details.isAt( CheckPointScheduler.class, "waitOngoingCheckpointCompletion" ) ); otherThreadExecutor.close();
@Test public void shouldApplyBackPressure() throws Exception { // given int backPressureThreshold = 10; BlockableMonitor monitor = new BlockableMonitor(); try ( OtherThreadExecutor<Void> t2 = new OtherThreadExecutor<>( "T2", null ); BadCollector badCollector = new BadCollector( NULL_OUTPUT_STREAM, UNLIMITED_TOLERANCE, COLLECT_ALL, backPressureThreshold, false, monitor ) ) { for ( int i = 0; i < backPressureThreshold; i++ ) { badCollector.collectDuplicateNode( i, i, "group" ); } // when Future<Object> enqueue = t2.executeDontWait( command( () -> badCollector.collectDuplicateNode( 999, 999, "group" ) ) ); t2.waitUntilWaiting( waitDetails -> waitDetails.isAt( BadCollector.class, "collect" ) ); monitor.unblock(); // then enqueue.get(); } }
@Test public void shouldMutexAccessBetweenInvalidateAndinstance() throws Exception { // GIVEN final CountDownLatch latch = new CountDownLatch( 1 ); final AtomicInteger initCalls = new AtomicInteger(); LazySingleReference<Integer> ref = new LazySingleReference<Integer>() { @Override protected Integer create() { awaitLatch( latch ); return initCalls.incrementAndGet(); } }; Future<Integer> t1Evaluate = t1.executeDontWait( evaluate( ref ) ); t1.waitUntilWaiting(); // WHEN Future<Void> t2Invalidate = t2.executeDontWait( invalidate( ref ) ); t2.waitUntilBlocked(); latch.countDown(); int e = t1Evaluate.get(); t2Invalidate.get(); // THEN assertEquals( "Evaluation", 1, e ); }
node.setProperty( TEST_PROPERTY_NAME, "b" ); Future<Void> propertySetFuture = secondTransactionExecutor.executeDontWait( state -> } ); secondTransactionExecutor.waitUntilWaiting( exclusiveLockWaitingPredicate() ); clockExecutor.execute( (OtherThreadExecutor.WorkerCommand<Void,Void>) state ->
@Test public void concurrently_creating_same_property_key_in_different_transactions_should_end_up_with_same_key_id() throws Exception { // GIVEN GraphDatabaseAPI db = (GraphDatabaseAPI) new TestGraphDatabaseFactory().newImpermanentDatabase(); OtherThreadExecutor<WorkerState> worker1 = new OtherThreadExecutor<>( "w1", new WorkerState( db ) ); OtherThreadExecutor<WorkerState> worker2 = new OtherThreadExecutor<>( "w2", new WorkerState( db ) ); worker1.execute( new BeginTx() ); worker2.execute( new BeginTx() ); // WHEN String key = "mykey"; worker1.execute( new CreateNodeAndSetProperty( key ) ); worker2.execute( new CreateNodeAndSetProperty( key ) ); worker1.execute( new FinishTx() ); worker2.execute( new FinishTx() ); worker1.close(); worker2.close(); // THEN assertEquals( 1, propertyKeyCount( db ) ); db.shutdown(); }
@Test public void shouldAbortStoreScanWaitOnDrop() throws Exception { // given the proxy structure FakePopulatingIndexProxy delegate = new FakePopulatingIndexProxy(); FlippableIndexProxy flipper = new FlippableIndexProxy( delegate ); OtherThreadExecutor<Void> waiter = cleanup.add( new OtherThreadExecutor<>( "Waiter", null ) ); // and a thread stuck in the awaitStoreScanCompletion loop Future<Object> waiting = waiter.executeDontWait( state -> flipper.awaitStoreScanCompleted() ); while ( !delegate.awaitCalled ) { Thread.sleep( 10 ); } // when flipper.drop(); // then the waiting should quickly be over waiting.get( 10, SECONDS ); }
@Override public void evaluate() throws Throwable { String threadName = name != null ? name + "-" + description.getDisplayName() : description.getDisplayName(); executor = new OtherThreadExecutor<>( threadName, timeout, unit, initialState() ); try { base.evaluate(); } finally { try { executor.close(); } finally { executor = null; } } } };
OtherThreadExecutor<Void> executor = cleanup.add( new OtherThreadExecutor<>( "Deferred", null ) ); executor.execute( (WorkerCommand<Void,Void>) state -> } ); executor.execute( (WorkerCommand<Void,Void>) state -> executor.execute( (WorkerCommand<Void,Void>) state ->
@Test public void shouldResumeWhenWritabilityChanged() throws Exception { TestThrottleLock lockOverride = new TestThrottleLock(); // given TransportThrottle throttle = newThrottleAndInstall( channel, lockOverride ); when( channel.isWritable() ).thenReturn( false ); Future<Void> completionFuture = otherThread.execute( state -> { throttle.acquire( channel ); return null; } ); otherThread.get().waitUntilWaiting(); // when when( channel.isWritable() ).thenReturn( true ); ArgumentCaptor<ChannelInboundHandler> captor = ArgumentCaptor.forClass( ChannelInboundHandler.class ); verify( channel.pipeline() ).addLast( captor.capture() ); captor.getValue().channelWritabilityChanged( context ); otherThread.get().awaitFuture( completionFuture ); assertThat( lockOverride.lockCallCount(), greaterThan( 0 ) ); assertThat( lockOverride.unlockCallCount(), is( 1 ) ); }
public WaitDetails waitUntilWaiting( Predicate<WaitDetails> correctWait ) throws TimeoutException { return waitUntilThreadState( correctWait, Thread.State.WAITING, Thread.State.TIMED_WAITING ); }
public <R> R execute( WorkerCommand<T, R> cmd ) throws Exception { return executeDontWait( cmd ).get(); }
public WaitDetails waitUntilBlocked() throws TimeoutException { return waitUntilBlocked( details -> true ); }
final CountDownLatch triggerExternalAccess = new CountDownLatch( 1 ); OtherThreadExecutor<Void> flippingThread = cleanup.add( new OtherThreadExecutor<>( "Flipping thread", null ) ); OtherThreadExecutor<Void> dropIndexThread = cleanup.add( new OtherThreadExecutor<>( "Drop index thread", null ) ); Future<Void> flipContextFuture = flippingThread.executeDontWait( startFlipAndWaitForLatchBeforeFinishing( flippable, triggerFinishFlip, triggerExternalAccess ) ); Future<Void> dropIndexFuture = dropIndexThread.executeDontWait( dropTheIndex( flippable ) ); dropIndexThread.waitUntilWaiting();