You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maka.apache.org by wy...@apache.org on 2026/09/02 09:36:17 UTC
(maka) 01/01: fix(desktop): keep shared session join progress continuous
This is an automated email from the ASF dual-hosted git repository.
M4n5ter pushed a commit to branch fix/session-collaboration-join-continuity
in repository https://gitbox.apache.org/repos/asf/maka.git
commit 509453d1cb8e21d39406e79507722ea5e4dd4063
Author: Wang <m4...@gmail.com>
AuthorDate: Wed Sep 2 17:35:45 2026 +0800
fix(desktop): keep shared session join progress continuous
Generated-by: Codex
---
.../runtime-host-collaboration-ipc-main.test.ts | 35 ++++++++++++
.../__tests__/runtime-host-desktop-manager.test.ts | 65 ++++++++++++++++++++++
.../runtime-host-guest-session-mounts.test.ts | 36 ++++++++++++
apps/desktop/src/main/runtime-host-boot.ts | 4 +-
.../main/runtime-host-collaboration-ipc-main.ts | 25 +++++++--
.../src/main/runtime-host-desktop-candidate.ts | 4 ++
.../src/main/runtime-host-desktop-manager.ts | 52 +++++++++++++++--
.../src/main/runtime-host-guest-session-mounts.ts | 17 ++++--
.../runtime-host/src/__tests__/peer-native.test.ts | 10 +++-
packages/runtime-host/src/client/host-profile.ts | 7 +++
packages/runtime-host/src/client/peer-client.ts | 7 ++-
11 files changed, 244 insertions(+), 18 deletions(-)
diff --git a/apps/desktop/src/main/__tests__/runtime-host-collaboration-ipc-main.test.ts b/apps/desktop/src/main/__tests__/runtime-host-collaboration-ipc-main.test.ts
index ce64f26182..c6c3d190d9 100644
--- a/apps/desktop/src/main/__tests__/runtime-host-collaboration-ipc-main.test.ts
+++ b/apps/desktop/src/main/__tests__/runtime-host-collaboration-ipc-main.test.ts
@@ -19,6 +19,7 @@
import assert from 'node:assert/strict';
import test from 'node:test';
+import { RuntimeHostOperationError } from '@maka/runtime-host/client';
import {
decodeCollaborationInvitationCode,
encodeCollaborationInvitationCode,
@@ -149,3 +150,37 @@ test('requires plaintext confirmation and reports the issued invitation routes',
{ kind: 'peer', coordinationRelayCount: 1 },
);
});
+
+test('treats an unavailable collaboration authority as an empty background inbox', async () => {
+ const handlers = new Map<string, IpcHandler>();
+ registerRuntimeHostCollaborationIpc(
+ {
+ async queryCollaborationTurnRequests() {
+ throw new RuntimeHostOperationError(
+ 'collaboration.turn-request.query',
+ 'operation_unavailable',
+ 'Runtime Host collaboration authority is unavailable',
+ );
+ },
+ } as unknown as Parameters<typeof registerRuntimeHostCollaborationIpc>[0],
+ {
+ handle(channel, listener) {
+ handlers.set(channel, listener);
+ },
+ },
+ async () => {
+ throw new Error('not used');
+ },
+ );
+ const query = handlers.get('session-collaboration:turn-request:query');
+ assert.ok(query);
+
+ assert.deepEqual(await query({} as Parameters<IpcHandler>[0]), {
+ canRequestTurns: false,
+ requests: [],
+ });
+ await assert.rejects(
+ query({} as Parameters<IpcHandler>[0], 'session-1'),
+ RuntimeHostOperationError,
+ );
+});
diff --git a/apps/desktop/src/main/__tests__/runtime-host-desktop-manager.test.ts b/apps/desktop/src/main/__tests__/runtime-host-desktop-manager.test.ts
index 2bbe8a467c..6869b50584 100644
--- a/apps/desktop/src/main/__tests__/runtime-host-desktop-manager.test.ts
+++ b/apps/desktop/src/main/__tests__/runtime-host-desktop-manager.test.ts
@@ -710,6 +710,50 @@ test('reconnects after a pairing candidate becomes bound to this Client', async
await manager.close();
});
+test('activates Guest access on a fresh stream without replaying route progress', async () => {
+ const local = candidateHarness({ hostId: 'host-a' });
+ const remoteHostId = 'a'.repeat(64);
+ const pending = candidateHarness({
+ hostId: remoteHostId,
+ finalizeReconnectRequired: true,
+ });
+ const active = candidateHarness({ hostId: remoteHostId });
+ const queue = [local.candidate, pending.candidate, active.candidate];
+ const phases: string[] = [];
+ const routeRefreshes: Array<boolean | undefined> = [];
+ const manager = await startRuntimeHostDesktopManager(
+ {} as DesktopRuntimeHostCandidateStartInput,
+ {
+ startCandidate: async (input) => {
+ if (input.profileTarget) {
+ routeRefreshes.push(input.refreshPeerRoutes);
+ input.onConnectionPhase?.('discovering');
+ input.onConnectionPhase?.('connecting');
+ }
+ return ready(queue.shift()!);
+ },
+ reconnectBackoff: { minMs: 0, maxMs: 0 },
+ },
+ );
+ await manager.mountGuest(
+ peerGuestTarget('shared-session'),
+ undefined,
+ (phase) => phases.push(phase),
+ );
+ let activations = 0;
+
+ await manager.finalizeGuestAccess('shared-session', undefined, () => {
+ activations += 1;
+ });
+
+ assert.deepEqual(phases, ['discovering', 'connecting']);
+ assert.deepEqual(routeRefreshes, [undefined, false]);
+ assert.equal(activations, 1);
+ assert.equal(pending.closeCalls, 1);
+ assert.equal(manager.current('shared-session')?.candidate, active.candidate);
+ await manager.close();
+});
+
for (const dispatch of ['not_dispatched', 'dispatched'] as const) {
test(`replays ${dispatch} pairing finalization after connection loss`, async () => {
const local = candidateHarness({ hostId: 'host-a' });
@@ -1635,3 +1679,24 @@ function remoteTarget(
credential: `credential-${target}`,
};
}
+
+function peerGuestTarget(
+ id: string,
+): NonNullable<DesktopRuntimeHostCandidateStartInput['profileTarget']> {
+ return {
+ profile: {
+ id,
+ name: id,
+ kind: 'remote',
+ transport: {
+ kind: 'libp2p-direct',
+ peerId: '12D3KooWpeer',
+ routeHints: ['/ip4/192.0.2.1/udp/41000/quic-v1'],
+ coordinationRelays: [],
+ },
+ rootId: 'a'.repeat(64),
+ access: 'session_guest',
+ },
+ credential: 'credential-peer',
+ };
+}
diff --git a/apps/desktop/src/main/__tests__/runtime-host-guest-session-mounts.test.ts b/apps/desktop/src/main/__tests__/runtime-host-guest-session-mounts.test.ts
index ba5ee594c5..45fe594828 100644
--- a/apps/desktop/src/main/__tests__/runtime-host-guest-session-mounts.test.ts
+++ b/apps/desktop/src/main/__tests__/runtime-host-guest-session-mounts.test.ts
@@ -61,6 +61,42 @@ test('retains a successful Guest mount and rehydrates the same authority after r
await second!.close();
});
+test('presents Guest import as one connection followed by access activation', async () => {
+ const progress: string[] = [];
+ const mounts = service(memoryStore(), {
+ mount: async (_target, _signal, onConnectionPhase) => {
+ onConnectionPhase?.('discovering');
+ onConnectionPhase?.('connecting');
+ onConnectionPhase?.('authenticating');
+ onConnectionPhase?.('handshaking');
+ onConnectionPhase?.('waiting_for_ready');
+ },
+ finalizeAccess: async (_mountId, _signal, onAccessActivated) => {
+ onAccessActivated?.();
+ },
+ });
+
+ const result = await mounts.importInvitation(
+ invitation('guest-progress'),
+ false,
+ 'import-progress',
+ (phase) => progress.push(phase),
+ );
+
+ assert.equal(result.kind, 'connected');
+ const visibleProgress = progress.filter((phase, index) => phase !== progress[index - 1]);
+ assert.deepEqual(visibleProgress, [
+ 'validating_invitation',
+ 'discovering_host',
+ 'preparing_route',
+ 'connecting',
+ 'authenticating',
+ 'finalizing_access',
+ 'loading_session',
+ ]);
+ await mounts.close();
+});
+
test('persists authenticated route rotation for reconnect and restart', async () => {
const store = memoryStore();
let observePeerEndpoint!: (endpoint: HostPeerEndpoint) => void;
diff --git a/apps/desktop/src/main/runtime-host-boot.ts b/apps/desktop/src/main/runtime-host-boot.ts
index 62c4d4f90e..cee0633822 100644
--- a/apps/desktop/src/main/runtime-host-boot.ts
+++ b/apps/desktop/src/main/runtime-host-boot.ts
@@ -593,9 +593,9 @@ const guestSessionMountService = createDesktopGuestSessionMountService({
},
);
},
- finalizeAccess: async (mountId, signal) => {
+ finalizeAccess: async (mountId, signal, onAccessActivated) => {
if (!runtimeHostManager) throw new Error('Runtime Host manager is unavailable');
- await runtimeHostManager.finalizeGuestAccess(mountId, signal);
+ await runtimeHostManager.finalizeGuestAccess(mountId, signal, onAccessActivated);
},
unmount: async (mountId) => {
if (!runtimeHostManager) return;
diff --git a/apps/desktop/src/main/runtime-host-collaboration-ipc-main.ts b/apps/desktop/src/main/runtime-host-collaboration-ipc-main.ts
index afe90c6f66..b55fb3a302 100644
--- a/apps/desktop/src/main/runtime-host-collaboration-ipc-main.ts
+++ b/apps/desktop/src/main/runtime-host-collaboration-ipc-main.ts
@@ -17,6 +17,7 @@
* under the License.
*/
+import { RuntimeHostOperationError } from '@maka/runtime-host/client';
import type { DesktopRuntimeHostClient } from './runtime-host-client.js';
import {
encodeDesktopCollaborationInvitation,
@@ -91,10 +92,18 @@ export function registerRuntimeHostCollaborationIpc(
handleReconnectableRead(
ipcMain,
'session-collaboration:turn-request:query',
- (_event, sessionId: unknown) =>
- client.queryCollaborationTurnRequests(
- sessionId === undefined ? undefined : requiredId(sessionId, 'Session'),
- ),
+ async (_event, sessionId: unknown) => {
+ const requestedSessionId =
+ sessionId === undefined ? undefined : requiredId(sessionId, 'Session');
+ try {
+ return await client.queryCollaborationTurnRequests(requestedSessionId);
+ } catch (error) {
+ if (requestedSessionId === undefined && isCollaborationInboxUnavailable(error)) {
+ return { canRequestTurns: false, requests: [] };
+ }
+ throw error;
+ }
+ },
);
ipcMain.handle(
'session-collaboration:turn-request:acknowledge',
@@ -127,6 +136,14 @@ export function registerRuntimeHostCollaborationIpc(
);
}
+function isCollaborationInboxUnavailable(error: unknown): boolean {
+ return (
+ error instanceof RuntimeHostOperationError &&
+ error.operation === 'collaboration.turn-request.query' &&
+ error.code === 'operation_unavailable'
+ );
+}
+
function requiredId(value: unknown, label: string): string {
if (
typeof value !== 'string' ||
diff --git a/apps/desktop/src/main/runtime-host-desktop-candidate.ts b/apps/desktop/src/main/runtime-host-desktop-candidate.ts
index 51fd7a84b7..a2f0685983 100644
--- a/apps/desktop/src/main/runtime-host-desktop-candidate.ts
+++ b/apps/desktop/src/main/runtime-host-desktop-candidate.ts
@@ -205,6 +205,7 @@ export interface DesktopRuntimeHostCandidateStartInput
readonly onExit?: (details: CandidateExitDetails) => void;
readonly candidateLaunchBarrier?: RuntimeHostCandidateLaunchBarrier;
readonly peerClient?: RuntimeHostPeerClient;
+ readonly refreshPeerRoutes?: boolean;
readonly onConnectionPhase?: (phase: RuntimeHostConnectionPhase) => void;
readonly onHostStatus?: (status: HostStatusResult) => void;
readonly profileTarget?: {
@@ -440,6 +441,9 @@ async function startProfileDesktopRuntimeHostCandidate(
: { handshakeTimeoutMs: input.handshakeTimeoutMs }),
readyTimeoutMs: input.electionDeadlineMs ?? 45_000,
...(input.peerClient === undefined ? {} : { peerClient: input.peerClient }),
+ ...(input.refreshPeerRoutes === undefined
+ ? {}
+ : { refreshPeerRoutes: input.refreshPeerRoutes }),
...(input.onConnectionPhase === undefined
? {}
: { onConnectionPhase: input.onConnectionPhase }),
diff --git a/apps/desktop/src/main/runtime-host-desktop-manager.ts b/apps/desktop/src/main/runtime-host-desktop-manager.ts
index 914aeb1b5b..4789227f8f 100644
--- a/apps/desktop/src/main/runtime-host-desktop-manager.ts
+++ b/apps/desktop/src/main/runtime-host-desktop-manager.ts
@@ -79,7 +79,11 @@ export interface RuntimeHostDesktopManager {
onConnectionPhase?: (phase: RuntimeHostConnectionPhase) => void,
onHostStatus?: (status: HostStatusResult) => void,
): Promise<void>;
- finalizeGuestAccess(mountId: string, signal?: AbortSignal): Promise<void>;
+ finalizeGuestAccess(
+ mountId: string,
+ signal?: AbortSignal,
+ onAccessActivated?: () => void,
+ ): Promise<void>;
unmountGuest(mountId: string): Promise<void>;
disable(profileId: string): Promise<void>;
waitUntilReady(
@@ -208,6 +212,8 @@ interface DesktopRuntimeHostTargetGeneration {
hostId?: string;
lifecycle?: RuntimeHostReconnectLifecycle<DesktopRuntimeHostCandidate>;
unsubscribeLifecycle?: () => void;
+ connectionPhaseObserver?: (phase: RuntimeHostConnectionPhase) => void;
+ skipPeerRouteRefreshOnce?: boolean;
lastCandidate?: {
readonly hostId: string;
readonly hostEpoch: string;
@@ -355,11 +361,21 @@ class RuntimeHostDesktopManagerImpl implements RuntimeHostDesktopManager {
return this.#mutateTarget(profileId, () => this.#finalizeAccessCredential(profileId));
}
- finalizeGuestAccess(mountId: string, signal?: AbortSignal): Promise<void> {
- return this.#mutateTarget(mountId, () => this.#finalizeAccessCredential(mountId, signal));
+ finalizeGuestAccess(
+ mountId: string,
+ signal?: AbortSignal,
+ onAccessActivated?: () => void,
+ ): Promise<void> {
+ return this.#mutateTarget(mountId, () =>
+ this.#finalizeAccessCredential(mountId, signal, onAccessActivated),
+ );
}
- async #finalizeAccessCredential(profileId: string, externalSignal?: AbortSignal): Promise<void> {
+ async #finalizeAccessCredential(
+ profileId: string,
+ externalSignal?: AbortSignal,
+ onAccessActivated?: () => void,
+ ): Promise<void> {
const target = this.#requireTarget(profileId);
if (target.target.profile.kind !== 'remote') {
throw new Error('Only remote Runtime Host profiles can finalize pairing');
@@ -390,7 +406,14 @@ class RuntimeHostDesktopManagerImpl implements RuntimeHostDesktopManager {
() => candidate.client.finalizeAccessCredential(remainingMs),
signal,
);
+ notifyAccessActivated(onAccessActivated);
if (finalized.reconnectRequired) {
+ if (
+ target.target.profile.kind === 'remote' &&
+ target.target.profile.transport.kind === 'libp2p-direct'
+ ) {
+ target.skipPeerRouteRefreshOnce = true;
+ }
await candidate.close();
await this.#waitForReadyCandidate(lifecycle, candidate, signal);
}
@@ -565,6 +588,10 @@ class RuntimeHostDesktopManagerImpl implements RuntimeHostDesktopManager {
});
try {
target.lifecycle = await this.#startLifecycle(target, false, signal);
+ // Import progress describes the initial connection only. Later
+ // reconnects have their own durable target state and must not restart the
+ // one-shot join UI from route discovery.
+ target.connectionPhaseObserver = undefined;
if (this.#closed) {
await target.lifecycle.close();
throw new Error('Desktop Runtime Host manager is closed');
@@ -863,6 +890,8 @@ class RuntimeHostDesktopManagerImpl implements RuntimeHostDesktopManager {
let takeoverHostEpoch: string | undefined;
let localRecoveryAttempted = false;
const inheritedExit = target.input.onExit;
+ let refreshPeerRoutes = target.skipPeerRouteRefreshOnce !== true;
+ target.skipPeerRouteRefreshOnce = false;
const tryRecoverLocalHost = async (): Promise<boolean> => {
if (target.input.profileTarget || localRecoveryAttempted || !this.recoverLocalHost) {
return false;
@@ -889,13 +918,15 @@ class RuntimeHostDesktopManagerImpl implements RuntimeHostDesktopManager {
isTargetActive: () => this.#ipcMain.isActive(target.epoch),
isTargetValid: () => target.valid,
onConnectionPhase: (phase) => {
- target.input.onConnectionPhase?.(phase);
+ target.connectionPhaseObserver?.(phase);
},
+ ...(refreshPeerRoutes ? {} : { refreshPeerRoutes: false }),
signal,
...(takeoverHostEpoch === undefined ? {} : { takeoverHostEpoch }),
},
target.observations,
);
+ refreshPeerRoutes = true;
} catch (error) {
signal.throwIfAborted();
if (await tryRecoverLocalHost()) continue;
@@ -1066,6 +1097,9 @@ class RuntimeHostDesktopManagerImpl implements RuntimeHostDesktopManager {
input,
target,
observations,
+ ...(input.onConnectionPhase
+ ? { connectionPhaseObserver: input.onConnectionPhase }
+ : {}),
state: {
epoch,
target,
@@ -1232,6 +1266,14 @@ function pairingFinalizeTimedOut(error: unknown): boolean {
);
}
+function notifyAccessActivated(observer: (() => void) | undefined): void {
+ try {
+ observer?.();
+ } catch {
+ // Presentation progress cannot control credential finalization.
+ }
+}
+
function withRuntimeHostTarget(
input: DesktopRuntimeHostCandidateStartInput,
profileTarget: DesktopRuntimeHostCandidateStartInput['profileTarget'],
diff --git a/apps/desktop/src/main/runtime-host-guest-session-mounts.ts b/apps/desktop/src/main/runtime-host-guest-session-mounts.ts
index 4b9e5a97e6..a5a008175e 100644
--- a/apps/desktop/src/main/runtime-host-guest-session-mounts.ts
+++ b/apps/desktop/src/main/runtime-host-guest-session-mounts.ts
@@ -135,7 +135,11 @@ export function createDesktopGuestSessionMountService(input: {
onConnectionPhase?: (phase: RuntimeHostConnectionPhase) => void,
onPeerEndpoint?: (endpoint: HostPeerEndpoint) => void,
) => Promise<void>;
- readonly finalizeAccess: (mountId: string, signal: AbortSignal) => Promise<void>;
+ readonly finalizeAccess: (
+ mountId: string,
+ signal: AbortSignal,
+ onAccessActivated?: () => void,
+ ) => Promise<void>;
readonly unmount: (mountId: string) => Promise<void>;
readonly wait?: (delayMs: number, signal: AbortSignal) => Promise<void>;
readonly onError?: (error: Error, mount: GuestSessionMount) => void;
@@ -225,7 +229,13 @@ export function createDesktopGuestSessionMountService(input: {
if (activation.kind === 'import') {
reportImportProgress(activation.onProgress, 'finalizing_access');
}
- const finalization = input.finalizeAccess(mount.mountId, activation.controller.signal);
+ const finalization = input.finalizeAccess(
+ mount.mountId,
+ activation.controller.signal,
+ activation.kind === 'import'
+ ? () => reportImportProgress(activation.onProgress, 'loading_session')
+ : undefined,
+ );
activation.finalization = finalization;
try {
await finalization;
@@ -576,10 +586,9 @@ function collaborationProgressForConnectionPhase(
case 'connecting':
return 'connecting';
case 'authenticating':
- return 'authenticating';
case 'handshaking':
case 'waiting_for_ready':
- return 'loading_session';
+ return 'authenticating';
}
}
diff --git a/packages/runtime-host/src/__tests__/peer-native.test.ts b/packages/runtime-host/src/__tests__/peer-native.test.ts
index 1e8c2d033b..c1cccb4200 100644
--- a/packages/runtime-host/src/__tests__/peer-native.test.ts
+++ b/packages/runtime-host/src/__tests__/peer-native.test.ts
@@ -156,7 +156,15 @@ module.exports = {
native.default.resolveConnect(3);
await control;
- await client.connect(peerConnectInput('ready'));
+ const preparedBeforeReopen = preparedPeerIds.length;
+ const reopenPhases: string[] = [];
+ await client.connect(
+ { ...peerConnectInput('ready'), refreshRoutes: false },
+ undefined,
+ (phase) => reopenPhases.push(phase),
+ );
+ assert.equal(preparedPeerIds.length, preparedBeforeReopen);
+ assert.deepEqual(reopenPhases, ['connecting']);
await client.connect(peerConnectInput('fallback'));
await assert.rejects(client.connect(peerConnectInput('unreachable')), (failure: unknown) => {
return failure instanceof RuntimeHostPeerError && failure.code === 'transit_unavailable';
diff --git a/packages/runtime-host/src/client/host-profile.ts b/packages/runtime-host/src/client/host-profile.ts
index 4ac5566570..c0f681ff8c 100644
--- a/packages/runtime-host/src/client/host-profile.ts
+++ b/packages/runtime-host/src/client/host-profile.ts
@@ -388,6 +388,7 @@ export async function connectRuntimeHostProfile(
readonly readyTimeoutMs?: number;
readonly sshInteraction?: RuntimeHostSshInteraction;
readonly peerClient?: RuntimeHostPeerClient;
+ readonly refreshPeerRoutes?: boolean;
readonly onConnectionPhase?: (phase: RuntimeHostConnectionPhase) => void;
readonly onHostStatus?: (status: HostStatusResult) => void;
},
@@ -445,6 +446,7 @@ export async function connectRemoteRuntimeHostProfile(
readonly readyTimeoutMs?: number;
readonly sshInteraction?: RuntimeHostSshInteraction;
readonly peerClient?: RuntimeHostPeerClient;
+ readonly refreshPeerRoutes?: boolean;
readonly onConnectionPhase?: (phase: RuntimeHostConnectionPhase) => void;
readonly onHostStatus?: (status: HostStatusResult) => void;
},
@@ -467,6 +469,9 @@ export async function connectRemoteRuntimeHostProfile(
expectedRootId: input.profile.rootId,
clientInstanceId: input.clientInstanceId,
peerClient: requireRuntimeHostPeerClient(input.peerClient),
+ ...(input.refreshPeerRoutes === undefined
+ ? {}
+ : { refreshPeerRoutes: input.refreshPeerRoutes }),
...(input.signal === undefined ? {} : { signal: input.signal }),
...(input.connectTimeoutMs === undefined ? {} : { connectTimeoutMs: input.connectTimeoutMs }),
...(input.handshakeTimeoutMs === undefined
@@ -593,6 +598,7 @@ export async function connectPeerRuntimeHost(input: {
readonly expectedRootId: string;
readonly clientInstanceId: string;
readonly peerClient: RuntimeHostPeerClient;
+ readonly refreshPeerRoutes?: boolean;
readonly signal?: AbortSignal;
readonly connectTimeoutMs?: number;
readonly handshakeTimeoutMs?: number;
@@ -607,6 +613,7 @@ export async function connectPeerRuntimeHost(input: {
routeHints: input.transport.routeHints,
coordinationRelays: input.transport.coordinationRelays,
directDeadlineMs: Math.min(input.connectTimeoutMs ?? 40_000, 120_000),
+ ...(input.refreshPeerRoutes === undefined ? {} : { refreshRoutes: input.refreshPeerRoutes }),
},
input.signal,
input.onConnectionPhase,
diff --git a/packages/runtime-host/src/client/peer-client.ts b/packages/runtime-host/src/client/peer-client.ts
index 705ba0f9fb..998b96dcbc 100644
--- a/packages/runtime-host/src/client/peer-client.ts
+++ b/packages/runtime-host/src/client/peer-client.ts
@@ -37,6 +37,7 @@ export interface RuntimeHostPeerConnectInput {
readonly coordinationRelays?: readonly string[];
readonly transitRelayPeerIds?: readonly string[];
readonly directDeadlineMs: number;
+ readonly refreshRoutes?: boolean;
}
export type RuntimeHostPeerConnectionPhase = 'discovering' | 'connecting';
@@ -242,8 +243,10 @@ class RuntimeHostPeerClientImpl implements RuntimeHostPeerClient {
signal?: AbortSignal,
onPhase?: (phase: RuntimeHostPeerConnectionPhase) => void,
): Promise<RuntimeHostPeerNativeStream> {
- notifyPhase(onPhase, 'discovering');
- await this.#prepareRoutes(input, signal);
+ if (input.refreshRoutes !== false) {
+ notifyPhase(onPhase, 'discovering');
+ await this.#prepareRoutes(input, signal);
+ }
notifyPhase(onPhase, 'connecting');
return this.#connect(input, signal, 'application');
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org