Skip to content

Commit 1808067

Browse files
committed
Enable Qute debugger by default
Signed-off-by: azerr <[email protected]>
1 parent e89ca76 commit 1808067

File tree

4 files changed

+78
-18
lines changed

4 files changed

+78
-18
lines changed

extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/debug/DebugQuteEngineObserver.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
* Observes the creation of Qute engines and attaches the Qute debugger in development mode.
1515
*
1616
* <p>
17-
* When a new {@link io.quarkus.qute.EngineBuilder} is observed and the application is running in
17+
* When a new {@link io.quarkus.qute.EngineBuilder} is observed and the application is started with "-DquteDebugPort"
18+
* and running in
1819
* {@link io.quarkus.runtime.LaunchMode#DEVELOPMENT development mode} with
1920
* {@code quarkus.qute.debug.enabled=true}, this observer:
2021
* <ul>
@@ -38,7 +39,11 @@ public class DebugQuteEngineObserver {
3839
* @param config the Qute configuration
3940
*/
4041
void configureEngine(@Observes EngineBuilder builder, QuteConfig config) {
41-
if (LaunchMode.current() == LaunchMode.DEVELOPMENT && config.debug().enabled()) {
42+
if (LaunchMode.current() == LaunchMode.DEVELOPMENT && config.debug().enabled() && registrar.getPort() != null) {
43+
// - in dev mode only
44+
// - quarkus.qute.debug.enabled=true
45+
// - Quarkus application is started with -DquteDebugPort
46+
// --> enable the Qute debugger.
4247
builder.enableTracing(true);
4348
builder.addEngineListener(registrar);
4449
}

extensions/qute/runtime/src/main/java/io/quarkus/qute/runtime/debug/QuteDebugConfig.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,19 @@ public interface QuteDebugConfig {
2323
* </p>
2424
*
2525
* <p>
26-
* <strong>Default value:</strong> {@code false}
26+
* <strong>Default value:</strong> {@code true}
2727
* </p>
2828
*
2929
* <p>
3030
* Example configuration:
3131
* </p>
3232
*
3333
* <pre>
34-
* quarkus.qute.debug.enabled = true
34+
* quarkus.qute.debug.enabled = false
3535
* </pre>
3636
*
3737
* @return {@code true} if Qute debug mode is active, {@code false} otherwise.
3838
*/
39-
@WithDefault("false")
39+
@WithDefault("true")
4040
boolean enabled();
4141
}

independent-projects/qute/debug/src/main/java/io/quarkus/qute/debug/adapter/RegisterDebugServerAdapter.java

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.io.IOException;
44
import java.net.ServerSocket;
5+
import java.net.Socket;
56
import java.util.HashSet;
67
import java.util.Set;
78
import java.util.concurrent.ExecutorService;
@@ -99,7 +100,12 @@ private DebuggeeAgent createAgentIfNeeded() {
99100
return agent;
100101
}
101102

102-
private Integer getPort() {
103+
/**
104+
* Returns the Qute debugger port defines with "-DquteDebugPort" environment variable and false otherwise.
105+
*
106+
* @return the Qute debugger port defines with "-DquteDebugPort" environment variable and false otherwise.
107+
*/
108+
public Integer getPort() {
103109
if (port != null) {
104110
return port;
105111
}
@@ -198,7 +204,6 @@ private synchronized void initializeAgentBlocking(int port, boolean suspend) {
198204
log("DAP client connected!");
199205
setupLauncher(client, false);
200206
trackedEngines.forEach(engine -> agent.track(engine));
201-
agent.setEnabled(true);
202207
} catch (IOException e) {
203208
if (serverSocket != null && !serverSocket.isClosed()) {
204209
e.printStackTrace();
@@ -218,7 +223,7 @@ private synchronized void initializeAgentBlocking(int port, boolean suspend) {
218223
}
219224

220225
public void dispose() {
221-
if (launcherFuture != null) {
226+
if (launcherFuture != null && !launcherFuture.isDone()) {
222227
launcherFuture.cancel(true);
223228
}
224229
log("Shutdown hook: closing server socket.");
@@ -249,7 +254,11 @@ public void reset() {
249254
agent.reset();
250255
trackedEngines.clear();
251256
if (!notInitializedEngines.isEmpty()) {
252-
notInitializedEngines.forEach(engine -> engine.removeTraceListener(initializeAgentListener));
257+
notInitializedEngines.forEach(engine -> {
258+
if (engine.getTraceManager() != null) {
259+
engine.removeTraceListener(initializeAgentListener);
260+
}
261+
});
253262
notInitializedEngines.clear();
254263
}
255264
}
@@ -262,7 +271,7 @@ public void reset() {
262271
* @param suspend true if suspend mode (used to wait after connection)
263272
* @throws IOException if socket streams cannot be accessed
264273
*/
265-
private void setupLauncher(java.net.Socket client, boolean suspend) throws IOException {
274+
private void setupLauncher(Socket client, boolean suspend) throws IOException {
266275
// Cancel previous launcher if needed
267276
if (launcherFuture != null && !launcherFuture.isDone()) {
268277
launcherFuture.cancel(true);
@@ -276,7 +285,11 @@ private void setupLauncher(java.net.Socket client, boolean suspend) throws IOExc
276285
launcherFuture = launcher.startListening();
277286

278287
if (!notInitializedEngines.isEmpty()) {
279-
notInitializedEngines.forEach(engine -> engine.removeTraceListener(initializeAgentListener));
288+
notInitializedEngines.forEach(engine -> {
289+
if (engine.getTraceManager() != null) {
290+
engine.removeTraceListener(initializeAgentListener);
291+
}
292+
});
280293
notInitializedEngines.clear();
281294
}
282295

independent-projects/qute/debug/src/main/java/io/quarkus/qute/debug/agent/DebuggeeAgent.java

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ public class DebuggeeAgent implements Debugger {
8383
/** The set of Qute engines being tracked for debugging. */
8484
private final Set<Engine> trackedEngine;
8585

86+
/**
87+
* Qute engines that currently have the {@link DebuggerTraceListener} attached.
88+
* <p>
89+
* Used to prevent adding the same listener multiple times to the same engine.
90+
* </p>
91+
*/
92+
private final Set<Engine> enginesWithDebugListener;
93+
8694
/** Indicates whether the debugging agent is enabled. */
8795
private boolean enabled;
8896

@@ -97,6 +105,7 @@ public DebuggeeAgent() {
97105
this.variablesRegistry = new VariablesRegistry();
98106
this.sourceTemplateRegistry = new SourceTemplateRegistry();
99107
this.trackedEngine = new HashSet<>();
108+
this.enginesWithDebugListener = new HashSet<>();
100109
this.evaluationSupport = new EvaluationSupport(this);
101110
this.completionSupport = new CompletionSupport(this);
102111
}
@@ -107,8 +116,14 @@ public DebuggeeAgent() {
107116
* @param engine the engine to track.
108117
*/
109118
public void track(Engine engine) {
119+
// Only track the engine once
110120
if (!trackedEngine.contains(engine)) {
111-
engine.addTraceListener(debugListener);
121+
// If the debugger is currently active (DAP client connected),
122+
// attach the debug listener immediately so trace events start flowing.
123+
if (isEnabled()) {
124+
addDebugListener(engine);
125+
}
126+
// Mark the engine as tracked so we can manage its listener later
112127
trackedEngine.add(engine);
113128
}
114129
}
@@ -336,13 +351,17 @@ void output(OutputEventArguments args) {
336351
* Unlocks and terminates all debuggee threads, then clears all tracked engines.
337352
*/
338353
public void unlockAllDebuggeeThreads() {
339-
for (RemoteThread thread : debuggees.values()) {
340-
thread.terminate();
341-
fireThreadEvent(new ThreadEvent(thread.getId(), ThreadStatus.EXITED));
354+
if (!debuggees.isEmpty()) {
355+
for (RemoteThread thread : debuggees.values()) {
356+
thread.terminate();
357+
fireThreadEvent(new ThreadEvent(thread.getId(), ThreadStatus.EXITED));
358+
}
359+
debuggees.clear();
360+
}
361+
if (!trackedEngine.isEmpty()) {
362+
trackedEngine.forEach(this::removeDebugListener);
363+
trackedEngine.clear();
342364
}
343-
debuggees.clear();
344-
trackedEngine.forEach(engine -> engine.removeTraceListener(debugListener));
345-
trackedEngine.clear();
346365
}
347366

348367
@Override
@@ -462,6 +481,29 @@ public SourceTemplateRegistry getSourceTemplateRegistry() {
462481
@Override
463482
public void setEnabled(boolean enabled) {
464483
this.enabled = enabled;
484+
if (enabled) {
485+
// A DAP client is now connected → attach the debug listener to all tracked engines
486+
trackedEngine.forEach(this::addDebugListener);
487+
} else {
488+
// The DAP client has disconnected → detach the debug listener from all tracked engines
489+
trackedEngine.forEach(this::removeDebugListener);
490+
}
491+
}
492+
493+
private void addDebugListener(Engine engine) {
494+
// Only attach the listener if the engine supports tracing (has a TraceManager)
495+
// and if it has not already been added.
496+
if (engine.getTraceManager() != null && !enginesWithDebugListener.contains(engine)) {
497+
engine.addTraceListener(debugListener);
498+
enginesWithDebugListener.add(engine);
499+
}
500+
}
501+
502+
private void removeDebugListener(Engine engine) {
503+
if (engine.getTraceManager() != null) {
504+
engine.removeTraceListener(debugListener);
505+
enginesWithDebugListener.remove(engine);
506+
}
465507
}
466508

467509
@Override

0 commit comments

Comments
 (0)