@Test(timeout = 5000) public void testAlreadyRelease() throws InterruptedException { ReusableLatch latch = new ReusableLatch(false); latch.release(); latch.await(); latch = new ReusableLatch(true); latch.await(); }
@Test(timeout = 5000) public void testRelease() { ReusableLatch latch = new ReusableLatch(false); AssertExtensions.assertBlocks(() -> latch.awaitUninterruptibly(), () -> latch.release()); }
/** * Add event to the infight * @return The EventNumber for the event. */ private long addToInflight(PendingEvent event) { synchronized (lock) { eventNumber++; log.trace("Adding event {} to inflight on writer {}", eventNumber, writerId); inflight.put(eventNumber, event); if (!needSuccessors.get()) { waitingInflight.reset(); } return eventNumber; } }
@Override @SneakyThrows(Exception.class) public void close() { ReusableLatch waitSignal = null; synchronized (this.stateLock) { if (this.closed) { return; } this.closed = true; if (this.activeCount != 0 || !this.pendingItems.isEmpty()) { // Setup a latch that will be released when the last item completes. this.emptyNotifier = new ReusableLatch(false); waitSignal = this.emptyNotifier; } } if (waitSignal != null) { // We have unfinished items. Wait for them. waitSignal.await(CLOSE_TIMEOUT_MILLIS); } }
container1.stopSignal = new ReusableLatch(); // Manually control when the Container actually shuts down. container1.fail(new IntentionalException()); val startContainer2 = registry.startContainer(containerId, TIMEOUT); Assert.assertFalse("startContainer() completed before previous container shut down (with failure).", startContainer2.isDone()); container1.stopSignal.release(); startContainer2.get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS); TestContainer container2 = (TestContainer) registry.getContainer(containerId); container2.stopSignal = new ReusableLatch(); // Manually control when the Container actually shuts down. container2.stopAsync(); val startContainer3 = registry.startContainer(containerId, TIMEOUT); Assert.assertFalse("startContainer() completed before previous container shut down (normally).", startContainer3.isDone()); container2.stopSignal.release(); startContainer3.get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS); TestContainer container3 = (TestContainer) registry.getContainer(containerId);
private void releaseIfEmptyInflight() { synchronized (lock) { if (inflight.isEmpty()) { log.trace("Inflight empty for writer {}", writerId); waitingInflight.release(); } } }
/** * Block until all events are acked by the server. */ private void waitForInflight() { Exceptions.handleInterrupted(() -> waitingInflight.await()); }
@Override public void close() { if (!this.closed.getAndSet(true)) { Futures.await(Services.stopAsync(this, executorService())); ReusableLatch signal = this.closeReleaseSignal; if (signal != null) { // Wait until we are told to complete. signal.awaitUninterruptibly(); } } }
/** * Tests the ability to detect a container failure and unregister the container in case the container fails on startup. */ @Test public void testContainerFailureOnStartup() throws Exception { final int containerId = 123; // We insert a ReusableLatch that will allow us to manually delay the TestContainer's shutdown/closing process // so that we have enough time to verify that calling getContainer() on a currently shutting down container will // throw the appropriate exception. ReusableLatch closeReleaseSignal = new ReusableLatch(); TestContainerFactory factory = new TestContainerFactory(new IntentionalException(), closeReleaseSignal); @Cleanup StreamSegmentContainerRegistry registry = new StreamSegmentContainerRegistry(factory, executorService()); AssertExtensions.assertThrows( "Unexpected exception thrown upon failed container startup.", registry.startContainer(containerId, TIMEOUT)::join, ex -> ex instanceof IntentionalException || (ex instanceof IllegalStateException && ex.getCause() instanceof IntentionalException)); AssertExtensions.assertThrows( "Container is registered even if it failed to start (and is currently shut down).", () -> registry.getContainer(containerId), ex -> ex instanceof ContainerNotFoundException); // Unblock container closing, which will, in turn, unblock its de-registration. closeReleaseSignal.release(); AssertExtensions.assertThrows( "Container is registered even if it failed to start (and has been unregistered).", () -> registry.getContainer(containerId), ex -> ex instanceof ContainerNotFoundException); }
private void releaseFlush() { flushLatch.release(); }
@Override public void flush() throws SegmentSealedException { //flushLatch is used to simulate a blocking Flush(). . Exceptions.handleInterrupted(() -> flushLatch.await()); throw new SegmentSealedException(segment.toString()); }
@Override protected void doStop() { executorService().execute(() -> { ReusableLatch signal = this.stopSignal; if (signal != null) { // Wait until we are told to stop. signal.awaitUninterruptibly(); } if (state() != State.FAILED && state() != State.TERMINATED && this.stopException != null) { notifyFailed(this.stopException); } else { notifyStopped(); } }); }
invoked.put(segment1, new ReusableLatch()); invoked.put(segment2, new ReusableLatch()); waitOn.put(segment1, new ReusableLatch()); waitOn.put(segment2, new ReusableLatch()); invoked.get(segment).release(); Exceptions.handleInterrupted(() -> waitOn.get(segment).await()); return null; }); invoked.get(segment1).await(LOCK_TIMEOUT_MILLIS); Assert.assertEquals("Unexpected number of active segments.", 1, s.getSegmentWithOngoingOperationsCount()); invoked.get(segment2).await(LOCK_TIMEOUT_MILLIS); Assert.assertEquals("Unexpected number of active segments.", 2, s.getSegmentWithOngoingOperationsCount()); waitOn.get(segment1).release(); waitOn.get(segment2).release();
connectionSetupCompleted = null; if (closed || throwable instanceof SegmentSealedException) { waitingInflight.release();
@Override public RevisionedImpl create(String scopedSteamName, Revision revision) { latch.awaitUninterruptibly(); return new RevisionedImpl(scopedSteamName, new RevisionImpl(revision.asImpl().getSegment(), num, num), String.valueOf(num)); }
@Before public void setUp() throws Exception { executor = Executors.newSingleThreadScheduledExecutor(); zkTestServer = new TestingServerStarter().start(); serviceBuilder = ServiceBuilder.newInMemoryBuilder(ServiceBuilderConfig.getDefaultConfig()); serviceBuilder.initialize(); StreamSegmentStore store = serviceBuilder.createStreamSegmentService(); server = new PravegaConnectionListener(false, servicePort, store, mock(TableStore.class)); server.startListening(); controllerWrapper = new ControllerWrapper(zkTestServer.getConnectString(), false, controllerPort, serviceHost, servicePort, containerCount); controllerWrapper.awaitRunning(); listenerLatch.reset(); listenerInvoked.set(false); }
@Test public void endOfStreamNotifierTest() throws Exception { AtomicBoolean listenerInvoked = new AtomicBoolean(); ReusableLatch latch = new ReusableLatch(); when(state.isEndOfData()).thenReturn(false).thenReturn(true); when(sync.getState()).thenReturn(state); Listener<EndOfDataNotification> listener1 = notification -> { log.info("listener 1 invoked"); listenerInvoked.set(true); latch.release(); }; Listener<EndOfDataNotification> listener2 = notification -> { }; EndOfDataNotifier notifier = new EndOfDataNotifier(system, sync, executor); notifier.registerListener(listener1); verify(executor, times(1)).scheduleAtFixedRate(any(Runnable.class), anyLong(), anyLong(), any(TimeUnit.class)); latch.await(); verify(state, times(2)).isEndOfData(); assertTrue(listenerInvoked.get()); notifier.registerListener(listener2); verify(executor, times(1)).scheduleAtFixedRate(any(Runnable.class), anyLong(), anyLong(), any(TimeUnit.class)); notifier.unregisterAllListeners(); verify(system, times(1)).removeListeners(EndOfDataNotification.class.getSimpleName()); }
this.emptyNotifier.release(); this.emptyNotifier = null;
@Override public RevisionedImpl applyTo(RevisionedImpl oldState, Revision newRevision) { latch.awaitUninterruptibly(); return new RevisionedImpl(oldState.scopedStreamName, new RevisionImpl(newRevision.asImpl().getSegment(), num, num), "" + num); } }