use of io.pravega.segmentstore.server.ContainerHandle in project pravega by pravega.
the class ZKSegmentContainerMonitor method close.
@Override
public void close() {
Preconditions.checkState(closed.compareAndSet(false, true));
try {
this.hostContainerMapNode.close();
} catch (IOException e) {
// Ignoring exception on shutdown.
log.warn("Failed to close hostContainerMapNode {}", e);
}
val task = this.assigmentTask.getAndSet(null);
if (task != null) {
task.cancel(true);
}
ArrayList<ContainerHandle> toClose = new ArrayList<>(this.handles.values());
ArrayList<CompletableFuture<Void>> results = new ArrayList<>();
for (ContainerHandle handle : toClose) {
results.add(this.registry.stopContainer(handle, CLOSE_TIMEOUT_PER_CONTAINER).thenAccept(v -> unregisterHandle(handle.getContainerId())));
}
// Wait for all the containers to be closed.
Futures.await(Futures.allOf(results), CLOSE_TIMEOUT_PER_CONTAINER.toMillis());
}
use of io.pravega.segmentstore.server.ContainerHandle in project pravega by pravega.
the class ZKSegmentContainerMonitor method stopContainer.
// Stop the container given its id.
private CompletableFuture<Void> stopContainer(int containerId) {
log.info("Stopping Container {}.", containerId);
ContainerHandle handle = handles.get(containerId);
if (handle == null) {
log.warn("Container {} handle is null, container is pending start or already unregistered.", containerId);
return null;
} else {
this.pendingTasks.add(containerId);
try {
return registry.stopContainer(handle, CLOSE_TIMEOUT_PER_CONTAINER).whenComplete((aVoid, throwable) -> {
if (throwable != null) {
log.warn("Stopping container {} failed: {}", containerId, throwable);
}
try {
// We remove the handle and don't attempt retry on stop container failures.
unregisterHandle(containerId);
} finally {
// The pending task has to be removed after the handle is removed to avoid inconsistencies
// with the container state.
// Using finally block to ensure this is always called, otherwise this will prevent other
// tasks from being attempted for this container id.
this.pendingTasks.remove(containerId);
}
});
} catch (Throwable e) {
// The pending task has to be removed on all failures to enable retries.
this.pendingTasks.remove(containerId);
throw e;
}
}
}
use of io.pravega.segmentstore.server.ContainerHandle in project pravega by pravega.
the class LocalSegmentContainerManager method close.
// endregion
// region AutoCloseable Implementation
@Override
public void close() {
if (!this.closed.getAndSet(true)) {
// Close all containers that are still open.
ArrayList<CompletableFuture<Void>> results = new ArrayList<>();
synchronized (this.handles) {
ArrayList<ContainerHandle> toClose = new ArrayList<>(this.handles.values());
for (ContainerHandle handle : toClose) {
results.add(this.registry.stopContainer(handle, CLOSE_TIMEOUT_PER_CONTAINER));
}
}
// Wait for all the containers to be closed.
Futures.await(Futures.allOf(results), CLOSE_TIMEOUT_PER_CONTAINER.toMillis());
}
}
use of io.pravega.segmentstore.server.ContainerHandle in project pravega by pravega.
the class ZKSegmentContainerMonitorTest method testShutdownNotYetStartedContainer.
@Test
public void testShutdownNotYetStartedContainer() throws Exception {
@Cleanup CuratorFramework zkClient = startClient();
initializeHostContainerMapping(zkClient);
SegmentContainerRegistry containerRegistry = createMockContainerRegistry();
@Cleanup ZKSegmentContainerMonitor segMonitor = createContainerMonitor(containerRegistry, zkClient);
segMonitor.initialize(Duration.ofSeconds(1));
// Simulate a container that takes a long time to start. Should be greater than a few monitor loops.
ContainerHandle containerHandle = mock(ContainerHandle.class);
when(containerHandle.getContainerId()).thenReturn(2);
CompletableFuture<ContainerHandle> startupFuture = Futures.delayedFuture(() -> CompletableFuture.completedFuture(containerHandle), 3000, executorService());
when(containerRegistry.startContainer(eq(2), any())).thenReturn(startupFuture);
// Use ZK to send that information to the Container Manager.
HashMap<Host, Set<Integer>> currentData = deserialize(zkClient, PATH);
currentData.put(PRAVEGA_SERVICE_ENDPOINT, Collections.singleton(2));
zkClient.setData().forPath(PATH, SerializationUtils.serialize(currentData));
// Verify it's not yet started.
verify(containerRegistry, timeout(1000).atLeastOnce()).startContainer(eq(2), any());
assertEquals(0, segMonitor.getRegisteredContainers().size());
// Now simulate shutting it down.
when(containerRegistry.stopContainer(any(), any())).thenReturn(CompletableFuture.completedFuture(null));
currentData.clear();
zkClient.setData().forPath(PATH, SerializationUtils.serialize(currentData));
verify(containerRegistry, timeout(10000).atLeastOnce()).stopContainer(any(), any());
Thread.sleep(2000);
assertEquals(0, segMonitor.getRegisteredContainers().size());
}
use of io.pravega.segmentstore.server.ContainerHandle in project pravega by pravega.
the class ZKSegmentContainerMonitorTest method testRetryOnExceptions.
@Test
public void testRetryOnExceptions() throws Exception {
@Cleanup CuratorFramework zkClient = startClient();
initializeHostContainerMapping(zkClient);
SegmentContainerRegistry containerRegistry = createMockContainerRegistry();
@Cleanup ZKSegmentContainerMonitor segMonitor = createContainerMonitor(containerRegistry, zkClient);
segMonitor.initialize(Duration.ofSeconds(1));
// Simulate a container that throws exception on start.
when(containerRegistry.startContainer(eq(2), any())).thenThrow(new RuntimeException());
// Use ZK to send that information to the Container Manager.
HashMap<Host, Set<Integer>> currentData = deserialize(zkClient, PATH);
currentData.put(PRAVEGA_SERVICE_ENDPOINT, Collections.singleton(2));
zkClient.setData().forPath(PATH, SerializationUtils.serialize(currentData));
// Verify that it does not start.
verify(containerRegistry, timeout(1000).atLeastOnce()).startContainer(eq(2), any());
assertEquals(0, segMonitor.getRegisteredContainers().size());
// Now simulate success for the same container.
ContainerHandle containerHandle = mock(ContainerHandle.class);
when(containerHandle.getContainerId()).thenReturn(2);
when(containerRegistry.startContainer(eq(2), any())).thenReturn(CompletableFuture.completedFuture(containerHandle));
// Verify that it retries and starts the same container again.
verify(containerRegistry, timeout(1000).atLeastOnce()).startContainer(eq(2), any());
// Using wait here to ensure the private data structure is updated.
// TODO: Removing dependency on sleep here and other places in this class
// - https://github.com/pravega/pravega/issues/1079
Thread.sleep(2000);
assertEquals(1, segMonitor.getRegisteredContainers().size());
}
Aggregations