fix(services): show the service port for debug sessions like for run (#1789)

A direct debug launch had no Run session to carry the app's HTTP port, so
its Services node only showed Debugging/Starting. The debugger now parses
the same embedded web server startup line as Run, publishes the port on
DebugServiceSession, and the node shows :port as soon as the app announces
it, exactly like a running service (#1718).

Signed-off-by: Inf1mum <[email protected]>
Цей коміт міститься в:
Vadim Lazuk authored and GitHub committed 2026-11-07 02:32:06 +08:00
1 джерело d0c3b9ba34
коміт b2253a8bc8
6 files changed
+84 -6

No files matched your search

+13
Переглянути файл
@@ -53,6 +53,19 @@ it("does not republish service metadata when console output changes", () => {
expect(useDebugRunSessions.getState().serviceSessions).toBe(summaries);
});
it("announces the app's web server port once it appears on the console", () => {
adoptSession(1, { runConfig: config });
const before = useDebugRunSessions.getState().serviceSessions;
expect(before).toHaveLength(1);
appendConsole(1, "stdout", "Tomcat started on port 8080 (http) with context path '/'\n");
const withPort = useDebugRunSessions.getState().serviceSessions;
expect(withPort).not.toBe(before);
expect(withPort).toMatchObject([{ id: 1, httpPort: 8080 }]);
// Later output without a new port keeps the announced one without republishing.
appendConsole(1, "stdout", "application output\n");
expect(useDebugRunSessions.getState().serviceSessions).toBe(withPort);
});
it("stops shared-process debugger roots without stopping their process until requested", async () => {
adoptSession(1, { runConfig: config, process: 7 });
await stopSession(1, { stopProcess: false });
+29
Переглянути файл
@@ -25,6 +25,7 @@ import {
} from "@/platform/ipc";
import { confirmTerminate } from "@/workbench/confirmTerminate";
import { maybeEditorService, notifications, toolWindowService, useDebugRunSessions } from "@/workbench/contributions";
import { startedPort } from "@/features/run/serverPort";
import { breakpointsOf, consumeTemporary, flushBreakpoints, refreshStates, resetStatuses } from "./breakpoints/store";
import { interpolateLog, logParts, suspends } from "./breakpoints/model";
import { syncSpecial, useSpecialBreakpoints } from "./breakpoints/special";
@@ -305,6 +306,7 @@ export function publishContext() {
startedAt: session.startedAt ?? 0,
status: paused ? ("paused" as const) : session.status,
processId: session.process,
httpPort: sessionHttpPort(session.id),
rerun: session.runConfig || session.launch ? () => void rerunSession(session.id) : null,
stop: (options?: { stopProcess?: boolean }) => stopSession(session.id, options),
show: () => {
@@ -351,6 +353,30 @@ export function publishContext() {
// --- console -----------------------------------------------------------------
/**
* The HTTP port the session's application announced on its console ("Tomcat started on
* port 8080"), the same embedded web server line the Run console is parsed for. Kept per
* session, so the Services node keeps the port after the line scrolls out of the buffer.
*/
const announcedPorts = new Map<DebugSessionId, number>();
export function sessionHttpPort(id: DebugSessionId): number | undefined {
let port: number | undefined;
for (const line of useDebug.getState().console[id] ?? []) {
const found = startedPort(line.text);
if (found !== null) port = found;
}
if (port !== undefined) announcedPorts.set(id, port);
else port = announcedPorts.get(id);
return port;
}
/** Republishes Services metadata only when a console announced a port it had not shown yet. */
function republishForPorts() {
const published = useDebugRunSessions.getState().serviceSessions;
if (published.some((d) => d.httpPort !== sessionHttpPort(d.id))) publishContext();
}
export function appendConsole(session: DebugSessionId, category: string, raw: string) {
if (!raw) return;
flushConsoleOutput();
@@ -364,6 +390,7 @@ export function appendConsole(session: DebugSessionId, category: string, raw: st
trimConsole(next);
return { console: { ...s.console, [session]: next } };
});
republishForPorts();
}
/**
@@ -406,6 +433,7 @@ function flushConsoleOutput() {
}
return { console: consoleBySession };
});
republishForPorts();
}
/** Split styled output at real line breaks, retaining partial lines across events. */
@@ -1078,6 +1106,7 @@ export function resetSessions() {
pendingOutput.length = 0;
cancelOutputFlush();
ansiStreams.clear();
announcedPorts.clear();
useDebug.setState({ sessions: {}, active: null, console: {}, stopSeq: 0 });
useExecutionPoint.setState({ path: null, line: 0, top: true, values: {}, variables: {} });
publishContext();