Make ensureWorkerRunning async with health checks
Co-authored-by: thedotmack <683968+thedotmack@users.noreply.github.com>
This commit is contained in:
@@ -126,9 +126,9 @@ function getObservations(db: SessionStore, sessionIds: string[]): Observation[]
|
||||
/**
|
||||
* Context Hook Main Logic
|
||||
*/
|
||||
function contextHook(input?: SessionStartInput, useColors: boolean = false, useIndexView: boolean = false): string {
|
||||
async function contextHook(input?: SessionStartInput, useColors: boolean = false, useIndexView: boolean = false): Promise<string> {
|
||||
// Ensure worker is running
|
||||
ensureWorkerRunning();
|
||||
await ensureWorkerRunning();
|
||||
|
||||
const cwd = input?.cwd ?? process.cwd();
|
||||
const project = cwd ? path.basename(cwd) : 'unknown-project';
|
||||
@@ -424,16 +424,17 @@ const forceColors = process.argv.includes('--colors'); // Add this line
|
||||
|
||||
if (stdin.isTTY || forceColors) { // Modify this line to include forceColors
|
||||
// Running manually from terminal - print formatted output with colors
|
||||
const contextOutput = contextHook(undefined, true, useIndexView);
|
||||
console.log(contextOutput);
|
||||
process.exit(0);
|
||||
contextHook(undefined, true, useIndexView).then(contextOutput => {
|
||||
console.log(contextOutput);
|
||||
process.exit(0);
|
||||
});
|
||||
} else {
|
||||
// Running from hook - wrap in hookSpecificOutput JSON format
|
||||
let input = '';
|
||||
stdin.on('data', (chunk) => input += chunk);
|
||||
stdin.on('end', () => {
|
||||
stdin.on('end', async () => {
|
||||
const parsed = input.trim() ? JSON.parse(input) : undefined;
|
||||
const contextOutput = contextHook(parsed, false, useIndexView);
|
||||
const contextOutput = await contextHook(parsed, false, useIndexView);
|
||||
const result = {
|
||||
hookSpecificOutput: {
|
||||
hookEventName: "SessionStart",
|
||||
|
||||
@@ -28,7 +28,7 @@ async function newHook(input?: UserPromptSubmitInput): Promise<void> {
|
||||
const project = path.basename(cwd);
|
||||
|
||||
// Ensure worker is running
|
||||
ensureWorkerRunning();
|
||||
await ensureWorkerRunning();
|
||||
|
||||
const db = new SessionStore();
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ async function saveHook(input?: PostToolUseInput): Promise<void> {
|
||||
}
|
||||
|
||||
// Ensure worker is running
|
||||
ensureWorkerRunning();
|
||||
await ensureWorkerRunning();
|
||||
|
||||
const db = new SessionStore();
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ async function summaryHook(input?: StopInput): Promise<void> {
|
||||
const { session_id } = input;
|
||||
|
||||
// Ensure worker is running
|
||||
ensureWorkerRunning();
|
||||
await ensureWorkerRunning();
|
||||
|
||||
const db = new SessionStore();
|
||||
|
||||
|
||||
+63
-19
@@ -4,17 +4,53 @@ import { getPackageRoot } from "./paths.js";
|
||||
|
||||
const FIXED_PORT = parseInt(process.env.CLAUDE_MEM_WORKER_PORT || "37777", 10);
|
||||
|
||||
/**
|
||||
* Check if worker is responsive by trying the health endpoint
|
||||
*/
|
||||
async function isWorkerHealthy(timeoutMs: number = 3000): Promise<boolean> {
|
||||
try {
|
||||
const response = await fetch(`http://127.0.0.1:${FIXED_PORT}/health`, {
|
||||
signal: AbortSignal.timeout(timeoutMs)
|
||||
});
|
||||
return response.ok;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for worker to become healthy
|
||||
*/
|
||||
async function waitForWorkerHealth(maxWaitMs: number = 10000): Promise<boolean> {
|
||||
const start = Date.now();
|
||||
const checkInterval = 100; // Check every 100ms
|
||||
|
||||
while (Date.now() - start < maxWaitMs) {
|
||||
if (await isWorkerHealthy(1000)) {
|
||||
return true;
|
||||
}
|
||||
// Wait before next check
|
||||
await new Promise(resolve => setTimeout(resolve, checkInterval));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure worker service is running
|
||||
* Checks if worker is already running before attempting to start
|
||||
* This prevents unnecessary restarts that could interrupt mid-action processing
|
||||
*/
|
||||
export function ensureWorkerRunning(): void {
|
||||
export async function ensureWorkerRunning(): Promise<void> {
|
||||
// First, check if worker is already healthy
|
||||
if (await isWorkerHealthy(1000)) {
|
||||
return; // Worker is already running and responsive
|
||||
}
|
||||
|
||||
const packageRoot = getPackageRoot();
|
||||
const pm2Path = path.join(packageRoot, "node_modules", ".bin", "pm2");
|
||||
const ecosystemPath = path.join(packageRoot, "ecosystem.config.cjs");
|
||||
|
||||
// Check if worker is already running
|
||||
// Check PM2 status to see if worker process exists
|
||||
const checkProcess = spawn(pm2Path, ["list", "--no-color"], {
|
||||
cwd: packageRoot,
|
||||
stdio: ["ignore", "pipe", "ignore"],
|
||||
@@ -25,24 +61,32 @@ export function ensureWorkerRunning(): void {
|
||||
output += data.toString();
|
||||
});
|
||||
|
||||
checkProcess.on("close", (code) => {
|
||||
// Check if 'claude-mem-worker' is in the PM2 list output and is 'online'
|
||||
const isRunning = output.includes("claude-mem-worker") && output.includes("online");
|
||||
|
||||
if (!isRunning) {
|
||||
// Only start if not already running
|
||||
spawn(pm2Path, ["start", ecosystemPath], {
|
||||
cwd: packageRoot,
|
||||
stdio: "ignore",
|
||||
});
|
||||
|
||||
// Simple wait - no complex health checks needed
|
||||
const start = Date.now();
|
||||
while (Date.now() - start < 200) {
|
||||
// Busy wait
|
||||
}
|
||||
}
|
||||
// Wait for PM2 list to complete
|
||||
await new Promise<void>((resolve) => {
|
||||
checkProcess.on("close", () => resolve());
|
||||
});
|
||||
|
||||
// Check if 'claude-mem-worker' is in the PM2 list output and is 'online'
|
||||
const isRunning = output.includes("claude-mem-worker") && output.includes("online");
|
||||
|
||||
if (!isRunning) {
|
||||
// Start the worker
|
||||
const startProcess = spawn(pm2Path, ["start", ecosystemPath], {
|
||||
cwd: packageRoot,
|
||||
stdio: "ignore",
|
||||
});
|
||||
|
||||
// Wait for PM2 start command to complete
|
||||
await new Promise<void>((resolve) => {
|
||||
startProcess.on("close", () => resolve());
|
||||
});
|
||||
}
|
||||
|
||||
// Wait for worker to become healthy (either just started or was starting)
|
||||
const healthy = await waitForWorkerHealth(10000);
|
||||
if (!healthy) {
|
||||
throw new Error("Worker failed to become healthy after starting");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user