Skip to content

Commit

Permalink
Merge pull request #11013 from stuartwdouglas/10998
Browse files Browse the repository at this point in the history
Remote dev clean up
  • Loading branch information
gsmet authored Jul 28, 2020
2 parents 135cca1 + c83bb84 commit d5e5539
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

Expand All @@ -29,6 +29,7 @@
import io.quarkus.bootstrap.model.PathsCollection;
import io.quarkus.deployment.util.ProcessUtil;
import io.quarkus.dev.appstate.ApplicationStateNotification;
import io.quarkus.dev.spi.DevModeType;

/**
* The main entry point for the dev mojo execution
Expand Down Expand Up @@ -135,11 +136,15 @@ public void start() throws Exception {
Properties buildSystemProperties = new Properties();
buildSystemProperties.putAll(context.getBuildSystemProperties());
bootstrapBuilder.setBuildSystemProperties(buildSystemProperties);

Map<String, Object> map = new HashMap<>();
map.put(DevModeContext.class.getName(), context);
map.put(DevModeType.class.getName(), DevModeType.LOCAL);
curatedApplication = bootstrapBuilder.setTest(context.isTest()).build().bootstrap();
realCloseable = (Closeable) curatedApplication.runInAugmentClassLoader(
context.getAlternateEntryPoint() == null ? IsolatedDevModeMain.class.getName()
: context.getAlternateEntryPoint(),
Collections.singletonMap(DevModeContext.class.getName(), context));
map);
} catch (Throwable t) {
log.error("Quarkus dev mode failed to start", t);
throw new RuntimeException(t);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import io.quarkus.deployment.builditem.ApplicationClassPredicateBuildItem;
import io.quarkus.deployment.codegen.CodeGenData;
import io.quarkus.deployment.util.FSWatchUtil;
import io.quarkus.dev.spi.DevModeType;
import io.quarkus.dev.spi.HotReplacementSetup;
import io.quarkus.runner.bootstrap.AugmentActionImpl;
import io.quarkus.runtime.ApplicationLifecycleManager;
Expand Down Expand Up @@ -183,7 +184,7 @@ public synchronized void restartApp(Set<String> changedResources) {
}
}

private RuntimeUpdatesProcessor setupRuntimeCompilation(DevModeContext context, Path appRoot)
private RuntimeUpdatesProcessor setupRuntimeCompilation(DevModeContext context, Path appRoot, DevModeType devModeType)
throws Exception {
if (!context.getAllModules().isEmpty()) {
ServiceLoader<CompilationProvider> serviceLoader = ServiceLoader.load(CompilationProvider.class);
Expand All @@ -201,7 +202,7 @@ private RuntimeUpdatesProcessor setupRuntimeCompilation(DevModeContext context,
return null;
}
RuntimeUpdatesProcessor processor = new RuntimeUpdatesProcessor(appRoot, context, compiler,
this::restartApp, null);
devModeType, this::restartApp, null);

for (HotReplacementSetup service : ServiceLoader.load(HotReplacementSetup.class,
curatedApplication.getBaseRuntimeClassLoader())) {
Expand Down Expand Up @@ -264,7 +265,7 @@ public void close() {

//the main entry point, but loaded inside the augmentation class loader
@Override
public void accept(CuratedApplication o, Map<String, Object> o2) {
public void accept(CuratedApplication o, Map<String, Object> params) {
Timing.staticInitStarted(o.getBaseRuntimeClassLoader());
//https://github.com/quarkusio/quarkus/issues/9748
//if you have an app with all daemon threads then the app thread
Expand All @@ -287,7 +288,7 @@ public void run() {
try {
curatedApplication = o;

Object potentialContext = o2.get(DevModeContext.class.getName());
Object potentialContext = params.get(DevModeContext.class.getName());
if (potentialContext instanceof DevModeContext) {
context = (DevModeContext) potentialContext;
} else {
Expand Down Expand Up @@ -336,7 +337,8 @@ public boolean test(String s) {
sourcePath -> module.addSourcePaths(singleton(sourcePath.toAbsolutePath().toString()))));
}
}
runtimeUpdatesProcessor = setupRuntimeCompilation(context, (Path) o2.get(APP_ROOT));
runtimeUpdatesProcessor = setupRuntimeCompilation(context, (Path) params.get(APP_ROOT),
(DevModeType) params.get(DevModeType.class.getName()));
if (runtimeUpdatesProcessor != null) {
runtimeUpdatesProcessor.checkForFileChange();
runtimeUpdatesProcessor.checkForChangedClasses();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import io.quarkus.deployment.mutability.DevModeTask;
import io.quarkus.deployment.pkg.PackageConfig;
import io.quarkus.deployment.pkg.steps.JarResultBuildStep;
import io.quarkus.dev.spi.DevModeType;
import io.quarkus.dev.spi.HotReplacementSetup;
import io.quarkus.dev.spi.RemoteDevState;
import io.quarkus.runner.bootstrap.AugmentActionImpl;
Expand Down Expand Up @@ -121,8 +122,10 @@ private RuntimeUpdatesProcessor setupRuntimeCompilation(DevModeContext context,
log.error("Failed to create compiler, runtime compilation will be unavailable", e);
return null;
}
//this is never the remote side
RuntimeUpdatesProcessor processor = new RuntimeUpdatesProcessor(applicationRoot, context, compiler,
this::regenerateApplication, new BiConsumer<DevModeContext.ModuleInfo, String>() {
DevModeType.REMOTE_LOCAL_SIDE, this::regenerateApplication,
new BiConsumer<DevModeContext.ModuleInfo, String>() {
@Override
public void accept(DevModeContext.ModuleInfo moduleInfo, String s) {
copiedStaticResources.computeIfAbsent(moduleInfo, ss -> new HashSet<>()).add(s);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import io.quarkus.bootstrap.runner.Timing;
import io.quarkus.deployment.util.FSWatchUtil;
import io.quarkus.deployment.util.FileUtil;
import io.quarkus.dev.spi.DevModeType;
import io.quarkus.dev.spi.HotReplacementContext;
import io.quarkus.dev.spi.HotReplacementSetup;

Expand All @@ -46,6 +47,7 @@ public class RuntimeUpdatesProcessor implements HotReplacementContext, Closeable
private final Path applicationRoot;
private final DevModeContext context;
private final ClassLoaderCompiler compiler;
private final DevModeType devModeType;
volatile Throwable compileProblem;

// file path -> isRestartNeeded
Expand Down Expand Up @@ -78,10 +80,12 @@ public class RuntimeUpdatesProcessor implements HotReplacementContext, Closeable
private final BiConsumer<DevModeContext.ModuleInfo, String> copyResourceNotification;

public RuntimeUpdatesProcessor(Path applicationRoot, DevModeContext context, ClassLoaderCompiler compiler,
Consumer<Set<String>> restartCallback, BiConsumer<DevModeContext.ModuleInfo, String> copyResourceNotification) {
DevModeType devModeType, Consumer<Set<String>> restartCallback,
BiConsumer<DevModeContext.ModuleInfo, String> copyResourceNotification) {
this.applicationRoot = applicationRoot;
this.context = context;
this.compiler = compiler;
this.devModeType = devModeType;
this.restartCallback = restartCallback;
this.copyResourceNotification = copyResourceNotification;
}
Expand Down Expand Up @@ -147,6 +151,11 @@ public boolean isTest() {
return context.isTest();
}

@Override
public DevModeType getDevModeType() {
return devModeType;
}

@Override
public boolean doScan(boolean userInitiated) throws IOException {
final long startNanoseconds = System.nanoTime();
Expand Down Expand Up @@ -200,6 +209,9 @@ public void consumeNoRestartChanges(Consumer<Set<String>> consumer) {

@Override
public Set<String> syncState(Map<String, String> fileHashes) {
if (getDevModeType() != DevModeType.REMOTE_SERVER_SIDE) {
throw new RuntimeException("Can only sync state on the server side of remote dev mode");
}
Set<String> ret = new HashSet<>();
try {
Map<String, String> ourHashes = new HashMap<>(IsolatedRemoteDevModeMain.createHashes(applicationRoot));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import io.quarkus.deployment.dev.DevModeContext;
import io.quarkus.deployment.dev.IsolatedDevModeMain;
import io.quarkus.deployment.pkg.steps.JarResultBuildStep;
import io.quarkus.dev.spi.DevModeType;

@SuppressWarnings("Unused")
public class DevModeTask {
Expand Down Expand Up @@ -65,6 +66,7 @@ public static Closeable main(Path appRoot) throws Exception {
Map<String, Object> map = new HashMap<>();
map.put(DevModeContext.class.getName(), context);
map.put(IsolatedDevModeMain.APP_ROOT, appRoot);
map.put(DevModeType.class.getName(), DevModeType.REMOTE_SERVER_SIDE);
return (Closeable) bootstrap.runInAugmentClassLoader(IsolatedDevModeMain.class.getName(),
map);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.quarkus.dev.spi;

public enum DevModeType {
LOCAL,
REMOTE_LOCAL_SIDE,
REMOTE_SERVER_SIDE
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ public interface HotReplacementContext {
*/
boolean isTest();

/**
* Will return true if this is the remote side of a remote dev session
*
* @return
*/
DevModeType getDevModeType();

/**
*
* @return {@code true} if a restart was performed, {@code false} otherwise
Expand Down
4 changes: 4 additions & 0 deletions docs/src/main/asciidoc/maven-tooling.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ on bare metal you can just set this via the `export QUARKUS_LAUNCH_DEVMODE=true`
docker start the image with `-e QUARKUS_LAUNCH_DEVMODE=true`. When the application starts you should now see the following
line in the logs: `Profile dev activated. Live Coding activated`.

NOTE: The remote side does not need to include Maven or any other development tools. The normal `fast-jar` Dockerfile
that is generated with a new Quarkus application is all you need. If you are using bare metal launch the Quarkus runner
jar, do not attempt to run normal devmode.

Now you need to connect your local agent to the remote host, using the `remote-dev` command:

[source,shell]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import io.quarkus.arc.Arc;
import io.quarkus.arc.runtime.BeanContainer;
import io.quarkus.bootstrap.runner.Timing;
import io.quarkus.dev.spi.DevModeType;
import io.quarkus.dev.spi.HotReplacementContext;
import io.quarkus.netty.runtime.virtual.VirtualAddress;
import io.quarkus.netty.runtime.virtual.VirtualChannel;
Expand Down Expand Up @@ -400,7 +401,8 @@ public void handle(RoutingContext event) {
}
});
}
if (launchMode == LaunchMode.DEVELOPMENT && liveReloadConfig.password.isPresent()) {
if (launchMode == LaunchMode.DEVELOPMENT && liveReloadConfig.password.isPresent()
&& hotReplacementContext.getDevModeType() == DevModeType.REMOTE_SERVER_SIDE) {
root = remoteSyncHandler = new RemoteSyncHandler(liveReloadConfig.password.get(), root, hotReplacementContext);
}
rootHandler = root;
Expand Down

0 comments on commit d5e5539

Please sign in to comment.