refactor: rename sockPath to listen in pid lock, add startup timing instrumentation

This commit is contained in:
Mohamed Boudra
2026-03-12 14:19:21 +07:00
parent 213f155c9c
commit 9f089be946
10 changed files with 124 additions and 63 deletions
+17 -1
View File
@@ -1,4 +1,4 @@
import { useEffect, useSyncExternalStore, useState } from 'react' import { useEffect, useRef, useSyncExternalStore, useState } from 'react'
import { usePathname, useRouter } from 'expo-router' import { usePathname, useRouter } from 'expo-router'
import { useDaemonRegistry } from '@/contexts/daemon-registry-context' import { useDaemonRegistry } from '@/contexts/daemon-registry-context'
import { shouldUseManagedDesktopDaemon } from '@/desktop/managed-runtime/managed-runtime' import { shouldUseManagedDesktopDaemon } from '@/desktop/managed-runtime/managed-runtime'
@@ -13,6 +13,7 @@ import {
} from './index-startup' } from './index-startup'
const STARTUP_TIMEOUT_MS = 30_000 const STARTUP_TIMEOUT_MS = 30_000
const APP_START_TIME = performance.now()
function useAnyHostOnline(serverIds: string[]): string | null { function useAnyHostOnline(serverIds: string[]): string | null {
const runtime = getHostRuntimeStore() const runtime = getHostRuntimeStore()
@@ -60,6 +61,17 @@ export default function Index() {
const [hasTimedOut, setHasTimedOut] = useState(false) const [hasTimedOut, setHasTimedOut] = useState(false)
const isDesktopStartupRace = shouldUseManagedDesktopDaemon() const isDesktopStartupRace = shouldUseManagedDesktopDaemon()
const onlineServerId = useAnyHostOnline(daemons.map((daemon) => daemon.serverId)) const onlineServerId = useAnyHostOnline(daemons.map((daemon) => daemon.serverId))
const startupLogged = useRef(false)
useEffect(() => {
if (onlineServerId && !startupLogged.current) {
startupLogged.current = true
console.info('[Startup] host online', {
serverId: onlineServerId,
elapsedMs: Math.round(performance.now() - APP_START_TIME),
})
}
}, [onlineServerId])
useEffect(() => { useEffect(() => {
const timer = setTimeout(() => { const timer = setTimeout(() => {
@@ -80,6 +92,10 @@ export default function Index() {
if (pathname !== '/' && pathname !== '') { if (pathname !== '/' && pathname !== '') {
return return
} }
console.info('[Startup] navigating to host route', {
serverId: onlineServerId,
elapsedMs: Math.round(performance.now() - APP_START_TIME),
})
router.replace(buildHostRootRoute(onlineServerId) as any) router.replace(buildHostRootRoute(onlineServerId) as any)
}, [onlineServerId, pathname, registryLoading, router]) }, [onlineServerId, pathname, registryLoading, router])
@@ -483,15 +483,20 @@ export function DaemonRegistryProvider({ children }: { children: ReactNode }) {
let cancelled = false let cancelled = false
const bootstrapDesktopStartup = async () => { const bootstrapDesktopStartup = async () => {
const t0 = performance.now()
const elapsed = () => Math.round(performance.now() - t0)
try { try {
const isE2E = await AsyncStorage.getItem(E2E_STORAGE_KEY) const isE2E = await AsyncStorage.getItem(E2E_STORAGE_KEY)
if (cancelled || isE2E) { if (cancelled || isE2E) {
return return
} }
console.info('[DaemonRegistry] desktop bootstrap: starting', { elapsedMs: elapsed() })
await Promise.allSettled([ await Promise.allSettled([
(async () => { (async () => {
console.info('[DaemonRegistry] desktop bootstrap: startManagedDaemon', { elapsedMs: elapsed() })
const daemon = await startManagedDaemon() const daemon = await startManagedDaemon()
console.info('[DaemonRegistry] desktop bootstrap: managed daemon ready', { elapsedMs: elapsed(), serverId: daemon.serverId })
if (cancelled || !daemon.serverId) { if (cancelled || !daemon.serverId) {
return return
} }
@@ -506,15 +511,18 @@ export function DaemonRegistryProvider({ children }: { children: ReactNode }) {
label: daemon.hostname ?? undefined, label: daemon.hostname ?? undefined,
connection, connection,
}) })
console.info('[DaemonRegistry] desktop bootstrap: host connection upserted', { elapsedMs: elapsed() })
})().catch((managedBootstrapError) => { })().catch((managedBootstrapError) => {
if (!cancelled) { if (!cancelled) {
console.warn( console.warn(
'[DaemonRegistry] Failed to bootstrap desktop daemon connection', '[DaemonRegistry] Failed to bootstrap desktop daemon connection',
{ elapsedMs: elapsed() },
managedBootstrapError managedBootstrapError
) )
} }
}), }),
(async () => { (async () => {
console.info('[DaemonRegistry] desktop bootstrap: probing localhost', { elapsedMs: elapsed() })
const { serverId, hostname } = await probeConnection( const { serverId, hostname } = await probeConnection(
{ {
id: `bootstrap:${DEFAULT_LOCALHOST_ENDPOINT}`, id: `bootstrap:${DEFAULT_LOCALHOST_ENDPOINT}`,
@@ -523,6 +531,7 @@ export function DaemonRegistryProvider({ children }: { children: ReactNode }) {
}, },
{ timeoutMs: DEFAULT_LOCALHOST_BOOTSTRAP_TIMEOUT_MS } { timeoutMs: DEFAULT_LOCALHOST_BOOTSTRAP_TIMEOUT_MS }
) )
console.info('[DaemonRegistry] desktop bootstrap: localhost probe succeeded', { elapsedMs: elapsed(), serverId })
if (cancelled) { if (cancelled) {
return return
} }
@@ -532,8 +541,9 @@ export function DaemonRegistryProvider({ children }: { children: ReactNode }) {
endpoint: DEFAULT_LOCALHOST_ENDPOINT, endpoint: DEFAULT_LOCALHOST_ENDPOINT,
label: hostname ?? undefined, label: hostname ?? undefined,
}) })
console.info('[DaemonRegistry] desktop bootstrap: direct connection upserted', { elapsedMs: elapsed() })
})().catch(() => { })().catch(() => {
// Best-effort startup race only; ignore if localhost isn't reachable. console.info('[DaemonRegistry] desktop bootstrap: localhost probe failed', { elapsedMs: elapsed() })
}), }),
]) ])
} catch (bootstrapError) { } catch (bootstrapError) {
+66 -45
View File
@@ -143,7 +143,9 @@ export type HostRuntimeStartOptions = {
autoProbe?: boolean; autoProbe?: boolean;
}; };
const PROBE_INTERVAL_MS = 10_000; const PROBE_TICK_MS = 2_000;
const PROBE_STEADY_MS = 10_000;
const PROBE_MAX_BACKOFF_MS = 30_000;
const ADAPTIVE_SWITCH_THRESHOLD_MS = 40; const ADAPTIVE_SWITCH_THRESHOLD_MS = 40;
const ADAPTIVE_SWITCH_CONSECUTIVE_PROBES = 3; const ADAPTIVE_SWITCH_CONSECUTIVE_PROBES = 3;
const DEFAULT_AGENT_DIRECTORY_PAGE_LIMIT = 200; const DEFAULT_AGENT_DIRECTORY_PAGE_LIMIT = 200;
@@ -419,19 +421,19 @@ function findConnectionById(
return host.connections.find((connection) => connection.id === connectionId) ?? null; return host.connections.find((connection) => connection.id === connectionId) ?? null;
} }
function selectInitialConnectionId(host: HostProfile): string | null { function probeIntervalForConnection(
if (host.connections.length === 0) { firstSeenAt: number,
return null; isActiveOnline: boolean,
now: number
): number {
if (isActiveOnline) {
return PROBE_STEADY_MS;
} }
if (host.preferredConnectionId) { const age = now - firstSeenAt;
const preferred = host.connections.find( if (age < 10_000) return 2_000;
(connection) => connection.id === host.preferredConnectionId if (age < 30_000) return 5_000;
); if (age < 60_000) return PROBE_STEADY_MS;
if (preferred) { return PROBE_MAX_BACKOFF_MS;
return preferred.id;
}
}
return host.connections[0]?.id ?? null;
} }
function createDefaultDeps(): HostRuntimeControllerDeps { function createDefaultDeps(): HostRuntimeControllerDeps {
@@ -507,6 +509,8 @@ export class HostRuntimeController {
private unsubscribeClientStatus: (() => void) | null = null; private unsubscribeClientStatus: (() => void) | null = null;
private probeIntervalHandle: ReturnType<typeof setInterval> | null = null; private probeIntervalHandle: ReturnType<typeof setInterval> | null = null;
private started = false; private started = false;
private connectionFirstSeenAt = new Map<string, number>();
private connectionLastProbedAt = new Map<string, number>();
private switchCandidateConnectionId: string | null = null; private switchCandidateConnectionId: string | null = null;
private switchCandidateHitCount = 0; private switchCandidateHitCount = 0;
private clientIdPromise: Promise<string> | null = null; private clientIdPromise: Promise<string> | null = null;
@@ -555,19 +559,12 @@ export class HostRuntimeController {
return; return;
} }
this.started = true; this.started = true;
this.trackConnectionFirstSeen();
await this.runProbeCycleNow(); await this.runProbeCycleNow();
if (options?.autoProbe !== false) {
if (!this.snapshot.activeConnectionId) {
const fallbackConnectionId = selectInitialConnectionId(this.host);
if (fallbackConnectionId) {
await this.switchToConnection({ connectionId: fallbackConnectionId });
}
}
if (options?.autoProbe !== false && PROBE_INTERVAL_MS > 0) {
this.probeIntervalHandle = setInterval(() => { this.probeIntervalHandle = setInterval(() => {
void this.runProbeCycleNow(); void this.runProbeCycleNow();
}, PROBE_INTERVAL_MS); }, PROBE_TICK_MS);
} }
} }
@@ -597,20 +594,8 @@ export class HostRuntimeController {
async updateHost(host: HostProfile): Promise<void> { async updateHost(host: HostProfile): Promise<void> {
this.host = host; this.host = host;
const activeConnectionId = this.snapshot.activeConnectionId; this.trackConnectionFirstSeen();
const activeConnection = findConnectionById(host, activeConnectionId); await this.runProbeCycleNow();
if (!activeConnection) {
await this.runProbeCycleNow();
if (this.snapshot.activeConnectionId) {
return;
}
const fallbackConnectionId = selectInitialConnectionId(host);
if (!fallbackConnectionId) {
await this.stop();
return;
}
await this.switchToConnection({ connectionId: fallbackConnectionId });
}
} }
ensureConnected(): void { ensureConnected(): void {
@@ -674,9 +659,29 @@ export class HostRuntimeController {
return; return;
} }
const probeByConnectionId = new Map<string, ConnectionProbeState>(); const now = performance.now();
const isOnline = this.snapshot.connectionStatus === "online";
const activeConnectionId = this.snapshot.activeConnectionId;
const connectionsToProbe = this.host.connections.filter((connection) => {
const lastProbed = this.connectionLastProbedAt.get(connection.id);
if (lastProbed == null) {
return true;
}
const firstSeen = this.connectionFirstSeenAt.get(connection.id) ?? now;
const isActiveOnline = isOnline && connection.id === activeConnectionId;
const interval = probeIntervalForConnection(firstSeen, isActiveOnline, now);
return now - lastProbed >= interval;
});
if (connectionsToProbe.length === 0) {
return;
}
const probeByConnectionId = new Map(this.snapshot.probeByConnectionId);
await Promise.all( await Promise.all(
this.host.connections.map(async (connection) => { connectionsToProbe.map(async (connection) => {
this.connectionLastProbedAt.set(connection.id, performance.now());
try { try {
const latencyMs = await this.deps.measureLatency({ const latencyMs = await this.deps.measureLatency({
host: this.host, host: this.host,
@@ -700,12 +705,12 @@ export class HostRuntimeController {
} }
this.updateSnapshot({ probeByConnectionId }); this.updateSnapshot({ probeByConnectionId });
const activeConnectionId = this.snapshot.activeConnectionId; const currentActiveConnectionId = this.snapshot.activeConnectionId;
const activeProbe = activeConnectionId const activeProbe = currentActiveConnectionId
? probeByConnectionId.get(activeConnectionId) ? probeByConnectionId.get(currentActiveConnectionId)
: null; : null;
if (!activeConnectionId || !findConnectionById(this.host, activeConnectionId)) { if (!currentActiveConnectionId || !findConnectionById(this.host, currentActiveConnectionId)) {
const nextConnectionId = selectBestConnection({ const nextConnectionId = selectBestConnection({
candidates: buildConnectionCandidates(this.host), candidates: buildConnectionCandidates(this.host),
probeByConnectionId, probeByConnectionId,
@@ -724,7 +729,7 @@ export class HostRuntimeController {
candidates: buildConnectionCandidates(this.host), candidates: buildConnectionCandidates(this.host),
probeByConnectionId, probeByConnectionId,
}); });
if (nextConnectionId && nextConnectionId !== activeConnectionId) { if (nextConnectionId && nextConnectionId !== currentActiveConnectionId) {
await this.switchToConnection({ await this.switchToConnection({
connectionId: nextConnectionId, connectionId: nextConnectionId,
expectedProbeVersion: requestVersion, expectedProbeVersion: requestVersion,
@@ -745,7 +750,7 @@ export class HostRuntimeController {
.sort((left, right) => left.latencyMs - right.latencyMs); .sort((left, right) => left.latencyMs - right.latencyMs);
const fastest = available[0] ?? null; const fastest = available[0] ?? null;
if (!fastest || fastest.connectionId === activeConnectionId) { if (!fastest || fastest.connectionId === currentActiveConnectionId) {
this.switchCandidateConnectionId = null; this.switchCandidateConnectionId = null;
this.switchCandidateHitCount = 0; this.switchCandidateHitCount = 0;
return; return;
@@ -839,6 +844,22 @@ export class HostRuntimeController {
}); });
} }
private trackConnectionFirstSeen(): void {
const now = performance.now();
const currentIds = new Set(this.host.connections.map((c) => c.id));
for (const id of this.connectionFirstSeenAt.keys()) {
if (!currentIds.has(id)) {
this.connectionFirstSeenAt.delete(id);
this.connectionLastProbedAt.delete(id);
}
}
for (const connection of this.host.connections) {
if (!this.connectionFirstSeenAt.has(connection.id)) {
this.connectionFirstSeenAt.set(connection.id, now);
}
}
}
private isCurrentSwitchRequest(version: number): boolean { private isCurrentSwitchRequest(version: number): boolean {
return version === this.switchRequestVersion; return version === this.switchRequestVersion;
} }
@@ -20,7 +20,7 @@ export interface LocalDaemonPidInfo {
startedAt?: string startedAt?: string
hostname?: string hostname?: string
uid?: number uid?: number
sockPath?: string listen?: string
} }
export interface LocalDaemonState { export interface LocalDaemonState {
@@ -164,7 +164,7 @@ function readPidFile(pidPath: string): LocalDaemonPidInfo | null {
startedAt: typeof parsed.startedAt === 'string' ? parsed.startedAt : undefined, startedAt: typeof parsed.startedAt === 'string' ? parsed.startedAt : undefined,
hostname: typeof parsed.hostname === 'string' ? parsed.hostname : undefined, hostname: typeof parsed.hostname === 'string' ? parsed.hostname : undefined,
uid: typeof parsed.uid === 'number' ? parsed.uid : undefined, uid: typeof parsed.uid === 'number' ? parsed.uid : undefined,
sockPath: typeof parsed.sockPath === 'string' ? parsed.sockPath : undefined, listen: typeof parsed.listen === 'string' ? parsed.listen : typeof parsed.sockPath === 'string' ? parsed.sockPath : undefined,
} }
} catch { } catch {
return null return null
@@ -322,7 +322,7 @@ export function resolveLocalDaemonState(options: { home?: string } = {}): LocalD
const logPath = path.join(home, DAEMON_LOG_FILENAME) const logPath = path.join(home, DAEMON_LOG_FILENAME)
const pidInfo = existsSync(pidPath) ? readPidFile(pidPath) : null const pidInfo = existsSync(pidPath) ? readPidFile(pidPath) : null
const running = pidInfo ? isProcessRunning(pidInfo.pid) : false const running = pidInfo ? isProcessRunning(pidInfo.pid) : false
const listen = pidInfo?.sockPath ?? config.listen const listen = pidInfo?.listen ?? config.listen
return { return {
home, home,
+2 -2
View File
@@ -75,8 +75,8 @@ function readPidSocketTarget(paseoHome: string): string | null {
} }
try { try {
const parsed = JSON.parse(readFileSync(pidPath, 'utf-8')) as { sockPath?: unknown } const parsed = JSON.parse(readFileSync(pidPath, 'utf-8')) as { listen?: unknown; sockPath?: unknown }
return typeof parsed.sockPath === 'string' ? parsed.sockPath : null return typeof parsed.listen === 'string' ? parsed.listen : typeof parsed.sockPath === 'string' ? parsed.sockPath : null
} catch { } catch {
return null return null
} }
@@ -48,7 +48,7 @@ console.log('=== CLI IPC Target Helpers ===\n')
mkdirSync(paseoHome, { recursive: true }) mkdirSync(paseoHome, { recursive: true })
writeFileSync( writeFileSync(
path.join(paseoHome, 'paseo.pid'), path.join(paseoHome, 'paseo.pid'),
JSON.stringify({ pid: process.pid, sockPath: '/tmp/paseo-from-pid.sock' }) JSON.stringify({ pid: process.pid, listen: '/tmp/paseo-from-pid.sock' })
) )
assert.deepStrictEqual(resolveDefaultDaemonHosts({ PASEO_HOME: paseoHome }), [ assert.deepStrictEqual(resolveDefaultDaemonHosts({ PASEO_HOME: paseoHome }), [
'unix:///tmp/paseo-from-pid.sock', 'unix:///tmp/paseo-from-pid.sock',
@@ -93,7 +93,7 @@ console.log('=== CLI IPC Target Helpers ===\n')
mkdirSync(paseoHome, { recursive: true }) mkdirSync(paseoHome, { recursive: true })
writeFileSync( writeFileSync(
path.join(paseoHome, 'paseo.pid'), path.join(paseoHome, 'paseo.pid'),
JSON.stringify({ pid: process.pid, sockPath: '/tmp/paseo-priority.sock' }) JSON.stringify({ pid: process.pid, listen: '/tmp/paseo-priority.sock' })
) )
assert.deepStrictEqual( assert.deepStrictEqual(
resolveDefaultDaemonHosts({ resolveDefaultDaemonHosts({
+3 -1
View File
@@ -536,8 +536,9 @@ pub fn run() {
garbage_collect_attachment_files garbage_collect_attachment_files
]) ])
.setup(|app| { .setup(|app| {
let setup_start = std::time::Instant::now();
log::info!( log::info!(
"[app] Paseo Desktop v{} starting", "[app] Paseo Desktop v{} setup starting",
app.package_info().version app.package_info().version
); );
@@ -645,6 +646,7 @@ pub fn run() {
} }
app.set_menu(menu)?; app.set_menu(menu)?;
log::info!("[app] setup complete ({}ms)", setup_start.elapsed().as_millis());
let window = app.get_webview_window("main").unwrap(); let window = app.get_webview_window("main").unwrap();
let window_clone = window.clone(); let window_clone = window.clone();
@@ -574,8 +574,10 @@ fn managed_daemon_status_internal(app: &AppHandle) -> Result<ManagedDaemonStatus
} }
fn start_managed_daemon_internal(app: &AppHandle) -> Result<ManagedDaemonStatus, String> { fn start_managed_daemon_internal(app: &AppHandle) -> Result<ManagedDaemonStatus, String> {
let t0 = std::time::Instant::now();
log::info!("[daemon] starting managed daemon"); log::info!("[daemon] starting managed daemon");
let status = ensure_runtime_ready_internal(app)?; let status = ensure_runtime_ready_internal(app)?;
log::info!("[daemon] runtime ready ({}ms)", t0.elapsed().as_millis());
let runtime_root = PathBuf::from(&status.runtime_root); let runtime_root = PathBuf::from(&status.runtime_root);
let manifest = load_runtime_manifest(&runtime_root)?; let manifest = load_runtime_manifest(&runtime_root)?;
let output = cli_command(&runtime_root, &manifest, &["start"])? let output = cli_command(&runtime_root, &manifest, &["start"])?
@@ -599,20 +601,21 @@ fn start_managed_daemon_internal(app: &AppHandle) -> Result<ManagedDaemonStatus,
stderr stderr
)); ));
} }
log::info!("[daemon] start command succeeded, waiting for daemon to be ready"); log::info!("[daemon] start command succeeded ({}ms), waiting for daemon to be ready", t0.elapsed().as_millis());
for attempt in 0..150 { for attempt in 0..150 {
let daemon_status = managed_daemon_status_internal(app)?; let daemon_status = managed_daemon_status_internal(app)?;
if daemon_status.status == "running" && !daemon_status.server_id.trim().is_empty() { if daemon_status.status == "running" && !daemon_status.server_id.trim().is_empty() {
log::info!( log::info!(
"[daemon] ready after {} attempts (pid={:?})", "[daemon] ready after {} attempts, {}ms (pid={:?})",
attempt + 1, attempt + 1,
t0.elapsed().as_millis(),
daemon_status.pid daemon_status.pid
); );
return Ok(daemon_status); return Ok(daemon_status);
} }
std::thread::sleep(std::time::Duration::from_millis(200)); std::thread::sleep(std::time::Duration::from_millis(200));
} }
log::warn!("[daemon] timed out waiting for daemon to become ready"); log::warn!("[daemon] timed out waiting for daemon to become ready ({}ms)", t0.elapsed().as_millis());
managed_daemon_status_internal(app) managed_daemon_status_internal(app)
} }
+11 -2
View File
@@ -167,6 +167,8 @@ export async function createPaseoDaemon(
rootLogger: Logger rootLogger: Logger
): Promise<PaseoDaemon> { ): Promise<PaseoDaemon> {
const logger = rootLogger.child({ module: "bootstrap" }); const logger = rootLogger.child({ module: "bootstrap" });
const bootstrapStart = performance.now();
const elapsed = () => `${(performance.now() - bootstrapStart).toFixed(0)}ms`;
const daemonVersion = resolveDaemonVersion(import.meta.url); const daemonVersion = resolveDaemonVersion(import.meta.url);
const pidLockMode = config.pidLock?.mode ?? "self"; const pidLockMode = config.pidLock?.mode ?? "self";
const pidLockOwnerPid = config.pidLock?.ownerPid; const pidLockOwnerPid = config.pidLock?.ownerPid;
@@ -177,6 +179,7 @@ export async function createPaseoDaemon(
await acquirePidLock(config.paseoHome, config.listen, { await acquirePidLock(config.paseoHome, config.listen, {
ownerPid: pidLockOwnerPid, ownerPid: pidLockOwnerPid,
}); });
logger.info({ elapsed: elapsed() }, "PID lock acquired");
} }
try { try {
@@ -328,6 +331,7 @@ export async function createPaseoDaemon(
agentStorage agentStorage
); );
await agentStorage.initialize(); await agentStorage.initialize();
logger.info({ elapsed: elapsed() }, "Agent storage initialized");
await bootstrapWorkspaceRegistries({ await bootstrapWorkspaceRegistries({
paseoHome: config.paseoHome, paseoHome: config.paseoHome,
agentStorage, agentStorage,
@@ -335,8 +339,10 @@ export async function createPaseoDaemon(
workspaceRegistry, workspaceRegistry,
logger, logger,
}); });
logger.info({ elapsed: elapsed() }, "Workspace registries bootstrapped");
const persistedRecords = await agentStorage.list(); const persistedRecords = await agentStorage.list();
logger.info( logger.info(
{ elapsed: elapsed() },
`Agent registry loaded (${persistedRecords.length} record${persistedRecords.length === 1 ? "" : "s"}); agents will initialize on demand` `Agent registry loaded (${persistedRecords.length} record${persistedRecords.length === 1 ? "" : "s"}); agents will initialize on demand`
); );
logger.info( logger.info(
@@ -518,6 +524,7 @@ export async function createPaseoDaemon(
openaiConfig: config.openai, openaiConfig: config.openai,
speechConfig: config.speech, speechConfig: config.speech,
}); });
logger.info({ elapsed: elapsed() }, "Speech runtime initialized");
wsServer = new VoiceAssistantWebSocketServer( wsServer = new VoiceAssistantWebSocketServer(
httpServer, httpServer,
@@ -567,6 +574,8 @@ export async function createPaseoDaemon(
wsServer?.publishSpeechReadiness(snapshot); wsServer?.publishSpeechReadiness(snapshot);
}); });
logger.info({ elapsed: elapsed() }, "Bootstrap complete, ready to start listening");
const start = async () => { const start = async () => {
// Start main HTTP server // Start main HTTP server
await new Promise<void>((resolve, reject) => { await new Promise<void>((resolve, reject) => {
@@ -584,11 +593,11 @@ export async function createPaseoDaemon(
if (listenTarget.type === "tcp") { if (listenTarget.type === "tcp") {
logger.info( logger.info(
{ host: listenTarget.host, port: listenTarget.port }, { host: listenTarget.host, port: listenTarget.port, elapsed: elapsed() },
`Server listening on http://${listenTarget.host}:${listenTarget.port}` `Server listening on http://${listenTarget.host}:${listenTarget.port}`
); );
} else { } else {
logger.info({ path: listenTarget.path }, `Server listening on ${listenTarget.path}`); logger.info({ path: listenTarget.path, elapsed: elapsed() }, `Server listening on ${listenTarget.path}`);
} }
if (relayEnabled) { if (relayEnabled) {
+3 -3
View File
@@ -8,7 +8,7 @@ export interface PidLockInfo {
startedAt: string; startedAt: string;
hostname: string; hostname: string;
uid: number; uid: number;
sockPath: string; listen: string;
} }
export class PidLockError extends Error { export class PidLockError extends Error {
@@ -43,7 +43,7 @@ function resolveOwnerPid(ownerPid?: number): number {
export async function acquirePidLock( export async function acquirePidLock(
paseoHome: string, paseoHome: string,
sockPath: string, listen: string,
options?: { ownerPid?: number } options?: { ownerPid?: number }
): Promise<void> { ): Promise<void> {
const pidPath = getPidFilePath(paseoHome); const pidPath = getPidFilePath(paseoHome);
@@ -85,7 +85,7 @@ export async function acquirePidLock(
startedAt: new Date().toISOString(), startedAt: new Date().toISOString(),
hostname: hostname(), hostname: hostname(),
uid: process.getuid?.() ?? 0, uid: process.getuid?.() ?? 0,
sockPath, listen,
}; };
let fd; let fd;