io.camunda.zeebe.broker.bootstrap.AbstractBrokerStartupStep Maven / Gradle / Ivy
/*
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH under
* one or more contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright ownership.
* Licensed under the Camunda License 1.0. You may not use this file
* except in compliance with the Camunda License 1.0.
*/
package io.camunda.zeebe.broker.bootstrap;
import static io.camunda.zeebe.scheduler.future.CompletableActorFuture.completedExceptionally;
import io.camunda.zeebe.scheduler.ConcurrencyControl;
import io.camunda.zeebe.scheduler.future.ActorFuture;
import io.camunda.zeebe.scheduler.startup.StartupStep;
import java.util.function.BiConsumer;
abstract class AbstractBrokerStartupStep implements StartupStep {
@Override
public final ActorFuture startup(
final BrokerStartupContext brokerStartupContext) {
return createFutureAndRun(
brokerStartupContext,
(concurrencyControl, future) ->
startupInternal(brokerStartupContext, concurrencyControl, future));
}
@Override
public final ActorFuture shutdown(
final BrokerStartupContext brokerShutdownContext) {
return createFutureAndRun(
brokerShutdownContext,
(concurrencyControl, future) ->
shutdownInternal(brokerShutdownContext, concurrencyControl, future));
}
abstract void startupInternal(
final BrokerStartupContext brokerStartupContext,
final ConcurrencyControl concurrencyControl,
final ActorFuture startupFuture);
abstract void shutdownInternal(
final BrokerStartupContext brokerShutdownContext,
final ConcurrencyControl concurrencyControl,
final ActorFuture shutdownFuture);
/**
* Helper function that tries to create a future and call a runnable. If an exception is thrown
* while creating the future, then this exception is forwarded to a dummy future
*/
final ActorFuture createFutureAndRun(
final BrokerStartupContext brokerStartupContext,
final BiConsumer> runnable) {
try {
final var concurrencyControl = brokerStartupContext.getConcurrencyControl();
final ActorFuture future = concurrencyControl.createFuture();
forwardExceptions(() -> runnable.accept(concurrencyControl, future), future);
return future;
} catch (final Exception e) {
return completedExceptionally(e);
}
}
/**
* helper function that forwards exceptions thrown by a synchronous block of code to a future
* object
*/
final void forwardExceptions(final Runnable r, final ActorFuture future) {
try {
r.run();
} catch (final Exception e) {
future.completeExceptionally(e);
}
}
/**
* helper function that consumes the result of a previous future. If the previous future completed
* exceptionally, this exception is forwarded to the future passed in as argument. Otherwise, it
* executed the runnable.
*/
final BiConsumer proceed(final Runnable r, final ActorFuture future) {
return (ok, error) -> {
if (error != null) {
future.completeExceptionally(error);
} else {
forwardExceptions(r, future);
}
};
}
}