Skip to content

Commit

Permalink
Fix #1468 Intermittent failure of CamelDevModeTest
Browse files Browse the repository at this point in the history
  • Loading branch information
ppalaga authored and lburgazzoli committed Jul 14, 2020
1 parent 0684fee commit 54bed57
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.apache.camel.quarkus.core.deployment.spi.ContainerBeansBuildItem;
import org.apache.camel.quarkus.core.deployment.spi.RuntimeCamelContextCustomizerBuildItem;
import org.apache.camel.quarkus.main.CamelMain;
import org.apache.camel.quarkus.main.CamelMainConfig;
import org.apache.camel.quarkus.main.CamelMainProducers;
import org.apache.camel.quarkus.main.CamelMainRecorder;
import org.apache.camel.quarkus.main.deployment.spi.CamelMainBuildItem;
Expand Down Expand Up @@ -140,14 +141,15 @@ CamelMainBuildItem main(
* after having processed a certain number of messages..
* </ul>
*
* @param index a reference to a {@link IndexView}
* @param beanContainer a reference to a fully initialized CDI bean container
* @param recorder the recorder.
* @param main a reference to a {@link CamelMain}.
* @param customizers a list of {@link org.apache.camel.quarkus.core.CamelContextCustomizer} that will be
* executed before starting the {@link CamelContext} at {@link ExecutionTime#RUNTIME_INIT}.
* @param runtimeTasks a placeholder to ensure all the runtime task are properly are done.
* @return a build item holding a {@link CamelRuntime} instance.
* @param index a reference to a {@link IndexView}
* @param beanContainer a reference to a fully initialized CDI bean container
* @param recorder the recorder.
* @param main a reference to a {@link CamelMain}.
* @param customizers a list of {@link org.apache.camel.quarkus.core.CamelContextCustomizer} that will be
* executed before starting the {@link CamelContext} at {@link ExecutionTime#RUNTIME_INIT}.
* @param runtimeTasks a placeholder to ensure all the runtime task are properly are done.
* @param camelMainConfig a {@link CamelMainConfig}
* @return a build item holding a {@link CamelRuntime} instance.
*/
@BuildStep
@Record(value = ExecutionTime.RUNTIME_INIT, optional = true)
Expand All @@ -161,7 +163,8 @@ CamelRuntimeBuildItem runtime(
CamelMainRecorder recorder,
CamelMainBuildItem main,
List<RuntimeCamelContextCustomizerBuildItem> customizers,
List<CamelRuntimeTaskBuildItem> runtimeTasks) {
List<CamelRuntimeTaskBuildItem> runtimeTasks,
CamelMainConfig camelMainConfig) {

// Run the customizer before starting the context to give a last chance
// to amend the Camel Context setup.
Expand All @@ -174,7 +177,10 @@ CamelRuntimeBuildItem runtime(
customizers.stream().map(RuntimeCamelContextCustomizerBuildItem::get).collect(Collectors.toList()));

return new CamelRuntimeBuildItem(
recorder.createRuntime(beanContainer.getValue(), main.getInstance()),
recorder.createRuntime(
beanContainer.getValue(),
main.getInstance(),
camelMainConfig.shutdown.timeout.toMillis()),
index.getIndex().getAnnotations(DotName.createSimple(QuarkusMain.class.getName())).isEmpty());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@
import org.apache.camel.spi.CamelBeanPostProcessor;
import org.apache.camel.spi.HasCamelContext;
import org.apache.camel.support.service.ServiceHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class CamelMain extends MainCommandLineSupport implements HasCamelContext {
private static final Logger LOGGER = LoggerFactory.getLogger(CamelMain.class);

private final AtomicBoolean engineStarted;

public CamelMain(CamelContext camelContext) {
Expand Down Expand Up @@ -182,7 +186,11 @@ public void await() throws InterruptedException {

@Override
public void await(long timeout, TimeUnit unit) throws InterruptedException {
latch.await(timeout, unit);
if (!latch.await(timeout, unit)) {
LOGGER.warn(
"Could not await stopping CamelMain within {} {}. You may want to increase camel.main.shutdown.timeout",
timeout, unit);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,28 @@
*/
package org.apache.camel.quarkus.main;

import java.time.Duration;

import io.quarkus.runtime.annotations.ConfigGroup;
import io.quarkus.runtime.annotations.ConfigItem;
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;

@ConfigRoot(name = "camel.main", phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED)
public class CamelMainConfig {

/**
* Build time configuration options for {@link CamelMain} shutdown.
*/
@ConfigItem
public ShutdownConfig shutdown;

@ConfigGroup
public static class ShutdownConfig {
/**
* A timeout (with millisecond precision) to wait for {@link CamelMain#stop()} to finish
*/
@ConfigItem(defaultValue = "PT3S")
public Duration timeout;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,11 @@ public void afterConfigure(BaseMainSupport main) {
});
}

public RuntimeValue<CamelRuntime> createRuntime(BeanContainer beanContainer, RuntimeValue<CamelMain> main) {
final CamelRuntime runtime = new CamelMainRuntime(main.getValue());
public RuntimeValue<CamelRuntime> createRuntime(
BeanContainer beanContainer,
RuntimeValue<CamelMain> main,
long shutdownTimeoutMs) {
final CamelRuntime runtime = new CamelMainRuntime(main.getValue(), shutdownTimeoutMs);

// register to the container
beanContainer.instance(CamelProducers.class).setRuntime(runtime);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.apache.camel.quarkus.main;

import java.util.Arrays;
import java.util.concurrent.TimeUnit;

import io.quarkus.runtime.Quarkus;
import org.apache.camel.CamelContext;
Expand All @@ -30,9 +31,11 @@
public class CamelMainRuntime implements CamelRuntime {
private static final Logger LOGGER = LoggerFactory.getLogger(CamelMainRuntime.class);
private final CamelMain main;
private final long shutdownTimeoutMs;

public CamelMainRuntime(CamelMain main) {
public CamelMainRuntime(CamelMain main, long shutdownTimeoutMs) {
this.main = main;
this.shutdownTimeoutMs = shutdownTimeoutMs;
}

@Override
Expand All @@ -53,7 +56,7 @@ public void start(String[] args) {
stop();
throw new RuntimeException(e);
}
}).start();
}, "camel-main").start();
} catch (Exception e) {
LOGGER.error("Failed to start application", e);
stop();
Expand All @@ -64,6 +67,12 @@ public void start(String[] args) {
@Override
public void stop() {
main.stop();
/* Wait till the Camel shutdown is finished in camel-main thread started in start(String[]) above */
try {
main.getShutdownStrategy().await(shutdownTimeoutMs, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}

@Override
Expand Down

0 comments on commit 54bed57

Please sign in to comment.