use of io.pravega.controller.store.checkpoint.CheckpointStore in project pravega by pravega.
the class ControllerServiceStarter method startUp.
@Override
protected void startUp() {
long traceId = LoggerHelpers.traceEnterWithContext(log, this.objectId, "startUp");
log.info("Initiating controller service startUp");
log.info("Event processors enabled = {}", serviceConfig.getEventProcessorConfig().isPresent());
log.info("Cluster listener enabled = {}", serviceConfig.isControllerClusterListenerEnabled());
log.info(" Host monitor enabled = {}", serviceConfig.getHostMonitorConfig().isHostMonitorEnabled());
log.info(" gRPC server enabled = {}", serviceConfig.getGRPCServerConfig().isPresent());
log.info(" REST server enabled = {}", serviceConfig.getRestServerConfig().isPresent());
final StreamMetadataStore streamStore;
final TaskMetadataStore taskMetadataStore;
final HostControllerStore hostStore;
final CheckpointStore checkpointStore;
try {
// Initialize the executor service.
controllerExecutor = ExecutorServiceHelpers.newScheduledThreadPool(serviceConfig.getThreadPoolSize(), "controllerpool");
retentionExecutor = ExecutorServiceHelpers.newScheduledThreadPool(Config.RETENTION_THREAD_POOL_SIZE, "retentionpool");
log.info("Creating the stream store");
streamStore = StreamStoreFactory.createStore(storeClient, controllerExecutor);
log.info("Creating the task store");
taskMetadataStore = TaskStoreFactory.createStore(storeClient, controllerExecutor);
log.info("Creating the host store");
hostStore = HostStoreFactory.createStore(serviceConfig.getHostMonitorConfig(), storeClient);
log.info("Creating the checkpoint store");
checkpointStore = CheckpointStoreFactory.create(storeClient);
// On each controller process restart, we use a fresh hostId,
// which is a combination of hostname and random GUID.
String hostName = getHostName();
Host host = new Host(hostName, getPort(), UUID.randomUUID().toString());
if (serviceConfig.getHostMonitorConfig().isHostMonitorEnabled()) {
// Start the Segment Container Monitor.
monitor = new SegmentContainerMonitor(hostStore, (CuratorFramework) storeClient.getClient(), new UniformContainerBalancer(), serviceConfig.getHostMonitorConfig().getHostMonitorMinRebalanceInterval());
log.info("Starting segment container monitor");
monitor.startAsync();
}
ClientConfig clientConfig = ClientConfig.builder().controllerURI(URI.create((serviceConfig.getGRPCServerConfig().get().isTlsEnabled() ? "tls://" : "tcp://") + "localhost")).trustStore(serviceConfig.getGRPCServerConfig().get().getTlsTrustStore()).validateHostName(false).build();
connectionFactory = new ConnectionFactoryImpl(clientConfig);
SegmentHelper segmentHelper = new SegmentHelper();
streamMetadataTasks = new StreamMetadataTasks(streamStore, hostStore, taskMetadataStore, segmentHelper, controllerExecutor, host.getHostId(), connectionFactory, serviceConfig.getGRPCServerConfig().get().isAuthorizationEnabled(), serviceConfig.getGRPCServerConfig().get().getTokenSigningKey());
streamTransactionMetadataTasks = new StreamTransactionMetadataTasks(streamStore, hostStore, segmentHelper, controllerExecutor, host.getHostId(), serviceConfig.getTimeoutServiceConfig(), connectionFactory, serviceConfig.getGRPCServerConfig().get().isAuthorizationEnabled(), serviceConfig.getGRPCServerConfig().get().getTokenSigningKey());
streamCutService = new StreamCutService(Config.BUCKET_COUNT, host.getHostId(), streamStore, streamMetadataTasks, retentionExecutor);
log.info("starting auto retention service asynchronously");
streamCutService.startAsync();
streamCutService.awaitRunning();
// Controller has a mechanism to track the currently active controller host instances. On detecting a failure of
// any controller instance, the failure detector stores the failed HostId in a failed hosts directory (FH), and
// invokes the taskSweeper.sweepOrphanedTasks for each failed host. When all resources under the failed hostId
// are processed and deleted, that failed HostId is removed from FH folder.
// Moreover, on controller process startup, it detects any hostIds not in the currently active set of
// controllers and starts sweeping tasks orphaned by those hostIds.
TaskSweeper taskSweeper = new TaskSweeper(taskMetadataStore, host.getHostId(), controllerExecutor, streamMetadataTasks);
TxnSweeper txnSweeper = new TxnSweeper(streamStore, streamTransactionMetadataTasks, serviceConfig.getTimeoutServiceConfig().getMaxLeaseValue(), controllerExecutor);
if (serviceConfig.isControllerClusterListenerEnabled()) {
cluster = new ClusterZKImpl((CuratorFramework) storeClient.getClient(), ClusterType.CONTROLLER);
}
controllerService = new ControllerService(streamStore, hostStore, streamMetadataTasks, streamTransactionMetadataTasks, new SegmentHelper(), controllerExecutor, cluster);
// Setup event processors.
setController(new LocalController(controllerService, serviceConfig.getGRPCServerConfig().get().isAuthorizationEnabled(), serviceConfig.getGRPCServerConfig().get().getTokenSigningKey()));
if (serviceConfig.getEventProcessorConfig().isPresent()) {
// Create ControllerEventProcessor object.
controllerEventProcessors = new ControllerEventProcessors(host.getHostId(), serviceConfig.getEventProcessorConfig().get(), localController, checkpointStore, streamStore, hostStore, segmentHelper, connectionFactory, streamMetadataTasks, controllerExecutor);
// Bootstrap and start it asynchronously.
log.info("Starting event processors");
controllerEventProcessors.bootstrap(streamTransactionMetadataTasks, streamMetadataTasks).thenAcceptAsync(x -> controllerEventProcessors.startAsync(), controllerExecutor);
}
// Setup and start controller cluster listener after all sweepers have been initialized.
if (serviceConfig.isControllerClusterListenerEnabled()) {
List<FailoverSweeper> failoverSweepers = new ArrayList<>();
failoverSweepers.add(taskSweeper);
failoverSweepers.add(txnSweeper);
if (serviceConfig.getEventProcessorConfig().isPresent()) {
assert controllerEventProcessors != null;
failoverSweepers.add(controllerEventProcessors);
}
controllerClusterListener = new ControllerClusterListener(host, cluster, controllerExecutor, failoverSweepers);
log.info("Starting controller cluster listener");
controllerClusterListener.startAsync();
}
// Start RPC server.
if (serviceConfig.getGRPCServerConfig().isPresent()) {
grpcServer = new GRPCServer(controllerService, serviceConfig.getGRPCServerConfig().get());
grpcServer.startAsync();
log.info("Awaiting start of rpc server");
grpcServer.awaitRunning();
}
// Start REST server.
if (serviceConfig.getRestServerConfig().isPresent()) {
restServer = new RESTServer(this.localController, controllerService, grpcServer.getPravegaAuthManager(), serviceConfig.getRestServerConfig().get(), connectionFactory);
restServer.startAsync();
log.info("Awaiting start of REST server");
restServer.awaitRunning();
}
// Wait for controller event processors to start.
if (serviceConfig.getEventProcessorConfig().isPresent()) {
log.info("Awaiting start of controller event processors");
controllerEventProcessors.awaitRunning();
}
// Wait for controller cluster listeners to start.
if (serviceConfig.isControllerClusterListenerEnabled()) {
log.info("Awaiting start of controller cluster listener");
controllerClusterListener.awaitRunning();
}
} finally {
LoggerHelpers.traceLeave(log, this.objectId, "startUp", traceId);
}
}
use of io.pravega.controller.store.checkpoint.CheckpointStore in project pravega by pravega.
the class ControllerEventProcessorsTest method testHandleOrphaned.
@Test(timeout = 10000)
public void testHandleOrphaned() {
Controller localController = mock(Controller.class);
CheckpointStore checkpointStore = mock(CheckpointStore.class);
StreamMetadataStore streamStore = mock(StreamMetadataStore.class);
HostControllerStore hostStore = mock(HostControllerStore.class);
ConnectionFactory connectionFactory = mock(ConnectionFactory.class);
StreamMetadataTasks streamMetadataTasks = mock(StreamMetadataTasks.class);
StreamTransactionMetadataTasks streamTransactionMetadataTasks = mock(StreamTransactionMetadataTasks.class);
executor = Executors.newSingleThreadScheduledExecutor();
ControllerEventProcessorConfig config = ControllerEventProcessorConfigImpl.withDefault();
EventProcessorSystem system = mock(EventProcessorSystem.class);
EventProcessorGroup<ControllerEvent> processor = new EventProcessorGroup<ControllerEvent>() {
@Override
public void notifyProcessFailure(String process) throws CheckpointStoreException {
}
@Override
public EventStreamWriter<ControllerEvent> getWriter() {
return null;
}
@Override
public Set<String> getProcesses() throws CheckpointStoreException {
return Sets.newHashSet("host1", "host2");
}
@Override
public Service startAsync() {
return null;
}
@Override
public boolean isRunning() {
return false;
}
@Override
public State state() {
return null;
}
@Override
public Service stopAsync() {
return null;
}
@Override
public void awaitRunning() {
}
@Override
public void awaitRunning(long timeout, TimeUnit unit) throws TimeoutException {
}
@Override
public void awaitTerminated() {
}
@Override
public void awaitTerminated(long timeout, TimeUnit unit) throws TimeoutException {
}
@Override
public Throwable failureCause() {
return null;
}
@Override
public void addListener(Listener listener, Executor executor) {
}
@Override
public void close() throws Exception {
}
};
try {
when(system.createEventProcessorGroup(any(), any())).thenReturn(processor);
} catch (CheckpointStoreException e) {
e.printStackTrace();
}
ControllerEventProcessors processors = new ControllerEventProcessors("host1", config, localController, checkpointStore, streamStore, hostStore, SegmentHelperMock.getSegmentHelperMock(), connectionFactory, streamMetadataTasks, system, executor);
processors.startAsync();
processors.awaitRunning();
assertTrue(Futures.await(processors.sweepFailedProcesses(() -> Sets.newHashSet("host1"))));
assertTrue(Futures.await(processors.handleFailedProcess("host1")));
processors.shutDown();
}
use of io.pravega.controller.store.checkpoint.CheckpointStore in project pravega by pravega.
the class EventProcessorTest method testEventProcessorCell.
@Test(timeout = 10000)
@SuppressWarnings("unchecked")
public void testEventProcessorCell() throws CheckpointStoreException, ReinitializationRequiredException {
CheckpointStore checkpointStore = CheckpointStoreFactory.createInMemoryStore();
CheckpointConfig.CheckpointPeriod period = CheckpointConfig.CheckpointPeriod.builder().numEvents(1).numSeconds(1).build();
CheckpointConfig checkpointConfig = CheckpointConfig.builder().type(CheckpointConfig.Type.Periodic).checkpointPeriod(period).build();
EventProcessorGroupConfig config = EventProcessorGroupConfigImpl.builder().eventProcessorCount(1).readerGroupName(READER_GROUP).streamName(STREAM_NAME).checkpointConfig(checkpointConfig).build();
int[] input = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int expectedSum = input.length * (input.length + 1) / 2;
List<MockEventRead<TestEvent>> inputEvents = new ArrayList<>(input.length);
for (int i = 0; i < input.length; i++) {
inputEvents.add(new MockEventRead<>(i, new TestEvent(input[i])));
}
inputEvents.add(new MockEventRead<>(input.length, new TestEvent(-1)));
EventProcessorSystem system = Mockito.mock(EventProcessorSystem.class);
Mockito.when(system.getProcess()).thenReturn(PROCESS);
EventStreamReader<TestEvent> reader = Mockito.mock(EventStreamReader.class);
checkpointStore.addReaderGroup(PROCESS, READER_GROUP);
// Test case 1. Actor does not throw any exception during normal operation.
Mockito.when(reader.readNextEvent(anyLong())).thenAnswer(new SequenceAnswer<>(inputEvents));
EventProcessorConfig<TestEvent> eventProcessorConfig = EventProcessorConfig.<TestEvent>builder().supplier(() -> new TestEventProcessor(false)).serializer(new JavaSerializer<>()).decider((Throwable e) -> ExceptionHandler.Directive.Stop).config(config).build();
testEventProcessor(system, eventProcessorConfig, reader, READER_ID, checkpointStore, expectedSum);
// Test case 2. Actor throws an error during normal operation, and Directive is to Resume on error.
Mockito.when(reader.readNextEvent(anyLong())).thenAnswer(new SequenceAnswer<>(inputEvents));
eventProcessorConfig = EventProcessorConfig.<TestEvent>builder().supplier(() -> new TestEventProcessor(true)).serializer(new JavaSerializer<>()).decider((Throwable e) -> (e instanceof IllegalArgumentException) ? ExceptionHandler.Directive.Resume : ExceptionHandler.Directive.Stop).config(config).build();
testEventProcessor(system, eventProcessorConfig, reader, READER_ID, checkpointStore, expectedSum);
// Test case 3. Actor throws an error during normal operation, and Directive is to Restart on error.
Mockito.when(reader.readNextEvent(anyLong())).thenAnswer(new SequenceAnswer<>(inputEvents));
eventProcessorConfig = EventProcessorConfig.<TestEvent>builder().supplier(() -> new TestEventProcessor(true)).serializer(new JavaSerializer<>()).decider((Throwable e) -> (e instanceof IllegalArgumentException) ? ExceptionHandler.Directive.Restart : ExceptionHandler.Directive.Stop).config(config).build();
testEventProcessor(system, eventProcessorConfig, reader, READER_ID, checkpointStore, 0);
// Test case 3. Actor throws an error during normal operation, and Directive is to Restart on error.
Mockito.when(reader.readNextEvent(anyLong())).thenAnswer(new SequenceAnswer<>(inputEvents));
eventProcessorConfig = EventProcessorConfig.<TestEvent>builder().supplier(() -> new RestartFailingEventProcessor(true)).serializer(new JavaSerializer<>()).decider((Throwable e) -> (e instanceof IllegalArgumentException) ? ExceptionHandler.Directive.Restart : ExceptionHandler.Directive.Stop).config(config).build();
testEventProcessor(system, eventProcessorConfig, reader, READER_ID, checkpointStore, 3);
// Test case 5. startup fails for an event processor
eventProcessorConfig = EventProcessorConfig.<TestEvent>builder().supplier(StartFailingEventProcessor::new).serializer(new JavaSerializer<>()).decider((Throwable e) -> ExceptionHandler.Directive.Stop).config(config).build();
checkpointStore.addReader(PROCESS, READER_GROUP, READER_ID);
EventProcessorCell<TestEvent> cell = new EventProcessorCell<>(eventProcessorConfig, reader, new EventStreamWriterMock<>(), system.getProcess(), READER_ID, 0, checkpointStore);
cell.startAsync();
cell.awaitTerminated();
Assert.assertTrue(true);
}
use of io.pravega.controller.store.checkpoint.CheckpointStore in project pravega by pravega.
the class EventProcessorTest method testEventProcessorGroup.
@Test(timeout = 10000)
public void testEventProcessorGroup() throws CheckpointStoreException, ReinitializationRequiredException {
int count = 4;
int initialCount = count / 2;
String systemName = "testSystem";
String readerGroupName = "testReaderGroup";
int[] input = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int expectedSum = input.length * (input.length + 1) / 2;
CheckpointStore checkpointStore = CheckpointStoreFactory.createInMemoryStore();
EventProcessorGroupConfig config = createEventProcessorGroupConfig(initialCount);
EventProcessorSystemImpl system = createMockSystem(systemName, PROCESS, SCOPE, createEventReaders(count, input), new EventStreamWriterMock<>(), readerGroupName);
EventProcessorConfig<TestEvent> eventProcessorConfig = EventProcessorConfig.<TestEvent>builder().supplier(() -> new TestEventProcessor(false)).serializer(new JavaSerializer<>()).decider((Throwable e) -> ExceptionHandler.Directive.Stop).config(config).build();
// Create EventProcessorGroup.
EventProcessorGroupImpl<TestEvent> group = (EventProcessorGroupImpl<TestEvent>) system.createEventProcessorGroup(eventProcessorConfig, checkpointStore);
group.awaitRunning();
// Add a few event processors to the group.
group.changeEventProcessorCount(count - initialCount);
long actualSum = 0;
for (EventProcessorCell<TestEvent> cell : group.getEventProcessorMap().values()) {
cell.awaitTerminated();
TestEventProcessor actor = (TestEventProcessor) cell.getActor();
actualSum += actor.sum;
}
assertEquals(count * expectedSum, actualSum);
// Stop the group, and await its termmination.
group.stopAsync();
group.awaitTerminated();
}
use of io.pravega.controller.store.checkpoint.CheckpointStore in project pravega by pravega.
the class EventProcessorTest method testFailingEventProcessorInGroup.
@Test(timeout = 10000)
public void testFailingEventProcessorInGroup() throws ReinitializationRequiredException, CheckpointStoreException {
String systemName = "testSystem";
String readerGroupName = "testReaderGroup";
int[] input = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
CheckpointStore checkpointStore = CheckpointStoreFactory.createInMemoryStore();
EventProcessorGroupConfig config = createEventProcessorGroupConfig(1);
EventProcessorSystemImpl system = createMockSystem(systemName, PROCESS, SCOPE, createEventReaders(1, input), new EventStreamWriterMock<>(), readerGroupName);
EventProcessorConfig<TestEvent> eventProcessorConfig = EventProcessorConfig.<TestEvent>builder().supplier(StartFailingEventProcessor::new).serializer(new JavaSerializer<>()).decider((Throwable e) -> ExceptionHandler.Directive.Stop).config(config).build();
// Create EventProcessorGroup.
EventProcessorGroupImpl<TestEvent> group = (EventProcessorGroupImpl<TestEvent>) system.createEventProcessorGroup(eventProcessorConfig, checkpointStore);
// awaitRunning should succeed.
group.awaitRunning();
Assert.assertTrue(true);
}
Aggregations