chore(instances): harden presence refresh and fix lint
This commit is contained in:
@@ -67,9 +67,9 @@ describe("statusCommand", () => {
|
||||
expect(logs.some((l) => l.includes("Active sessions"))).toBe(true);
|
||||
expect(logs.some((l) => l.includes("Default model"))).toBe(true);
|
||||
expect(logs.some((l) => l.includes("tokens:"))).toBe(true);
|
||||
expect(logs.some((l) => l.includes("flags:") && l.includes("verbose:on"))).toBe(
|
||||
true,
|
||||
);
|
||||
expect(
|
||||
logs.some((l) => l.includes("flags:") && l.includes("verbose:on")),
|
||||
).toBe(true);
|
||||
expect(mocks.logWebSelfId).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -218,7 +218,9 @@ export async function statusCommand(
|
||||
const defaultCtx = defaults.contextTokens
|
||||
? ` (${formatKTokens(defaults.contextTokens)} ctx)`
|
||||
: "";
|
||||
runtime.log(info(`Default model: ${defaults.model ?? "unknown"}${defaultCtx}`));
|
||||
runtime.log(
|
||||
info(`Default model: ${defaults.model ?? "unknown"}${defaultCtx}`),
|
||||
);
|
||||
runtime.log(info(`Active sessions: ${summary.sessions.count}`));
|
||||
if (summary.sessions.recent.length > 0) {
|
||||
runtime.log("Recent sessions:");
|
||||
|
||||
@@ -7,7 +7,10 @@ import { describe, expect, it } from "vitest";
|
||||
import { acquireRelayLock, RelayLockError } from "./relay-lock.js";
|
||||
|
||||
const newLockPath = () =>
|
||||
path.join(os.tmpdir(), `clawdis-relay-lock-test-${process.pid}-${Math.random().toString(16).slice(2)}.sock`);
|
||||
path.join(
|
||||
os.tmpdir(),
|
||||
`clawdis-relay-lock-test-${process.pid}-${Math.random().toString(16).slice(2)}.sock`,
|
||||
);
|
||||
|
||||
describe("relay-lock", () => {
|
||||
it("prevents concurrent relay instances and releases cleanly", async () => {
|
||||
@@ -16,7 +19,9 @@ describe("relay-lock", () => {
|
||||
const release1 = await acquireRelayLock(lockPath);
|
||||
expect(fs.existsSync(lockPath)).toBe(true);
|
||||
|
||||
await expect(acquireRelayLock(lockPath)).rejects.toBeInstanceOf(RelayLockError);
|
||||
await expect(acquireRelayLock(lockPath)).rejects.toBeInstanceOf(
|
||||
RelayLockError,
|
||||
);
|
||||
|
||||
await release1();
|
||||
expect(fs.existsSync(lockPath)).toBe(false);
|
||||
|
||||
@@ -16,7 +16,9 @@ type ReleaseFn = () => Promise<void>;
|
||||
* the next start will detect ECONNREFUSED when connecting and clean the stale path
|
||||
* before retrying. This keeps the lock self-healing without manual pidfile cleanup.
|
||||
*/
|
||||
export async function acquireRelayLock(lockPath = DEFAULT_LOCK_PATH): Promise<ReleaseFn> {
|
||||
export async function acquireRelayLock(
|
||||
lockPath = DEFAULT_LOCK_PATH,
|
||||
): Promise<ReleaseFn> {
|
||||
// Fast path: try to listen on the lock path.
|
||||
const attemptListen = (): Promise<net.Server> =>
|
||||
new Promise((resolve, reject) => {
|
||||
@@ -33,7 +35,9 @@ export async function acquireRelayLock(lockPath = DEFAULT_LOCK_PATH): Promise<Re
|
||||
|
||||
client.once("connect", () => {
|
||||
client.destroy();
|
||||
reject(new RelayLockError("another relay instance is already running"));
|
||||
reject(
|
||||
new RelayLockError("another relay instance is already running"),
|
||||
);
|
||||
});
|
||||
|
||||
client.once("error", (connErr: NodeJS.ErrnoException) => {
|
||||
@@ -84,7 +88,11 @@ export async function acquireRelayLock(lockPath = DEFAULT_LOCK_PATH): Promise<Re
|
||||
process.exit(0);
|
||||
};
|
||||
|
||||
cleanupSignals.forEach((sig) => process.once(sig, handleSignal));
|
||||
for (const sig of cleanupSignals) {
|
||||
process.once(sig, () => {
|
||||
void handleSignal();
|
||||
});
|
||||
}
|
||||
process.once("exit", () => {
|
||||
// Exit handler must be sync-safe; release is async but close+rm are fast.
|
||||
void release();
|
||||
|
||||
@@ -59,6 +59,17 @@ function ensureSelfPresence() {
|
||||
}
|
||||
}
|
||||
|
||||
function touchSelfPresence() {
|
||||
const host = os.hostname();
|
||||
const key = host.toLowerCase();
|
||||
const existing = entries.get(key);
|
||||
if (existing) {
|
||||
entries.set(key, { ...existing, ts: Date.now() });
|
||||
} else {
|
||||
initSelfPresence();
|
||||
}
|
||||
}
|
||||
|
||||
initSelfPresence();
|
||||
|
||||
function parsePresence(text: string): SystemPresence {
|
||||
@@ -96,5 +107,6 @@ export function updateSystemPresence(text: string) {
|
||||
|
||||
export function listSystemPresence(): SystemPresence[] {
|
||||
ensureSelfPresence();
|
||||
touchSelfPresence();
|
||||
return [...entries.values()].sort((a, b) => b.ts - a.ts);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user