gitnexus 1.6.4-rc.67 → 1.6.4-rc.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -36,6 +36,30 @@ export function resolveWorkerPoolOptions(options = {}) {
|
|
|
36
36
|
timeoutBackoffFactor: positiveInteger(options.timeoutBackoffFactor) ?? DEFAULT_TIMEOUT_BACKOFF_FACTOR,
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
|
+
function waitForWorkerOnline(worker) {
|
|
40
|
+
return new Promise((resolve, reject) => {
|
|
41
|
+
const cleanup = () => {
|
|
42
|
+
worker.removeListener('online', onOnline);
|
|
43
|
+
worker.removeListener('error', onError);
|
|
44
|
+
worker.removeListener('exit', onExit);
|
|
45
|
+
};
|
|
46
|
+
const onOnline = () => {
|
|
47
|
+
cleanup();
|
|
48
|
+
resolve();
|
|
49
|
+
};
|
|
50
|
+
const onError = (err) => {
|
|
51
|
+
cleanup();
|
|
52
|
+
reject(err);
|
|
53
|
+
};
|
|
54
|
+
const onExit = (code) => {
|
|
55
|
+
cleanup();
|
|
56
|
+
reject(new Error(`Replacement worker exited with code ${code} before coming online`));
|
|
57
|
+
};
|
|
58
|
+
worker.once('online', onOnline);
|
|
59
|
+
worker.once('error', onError);
|
|
60
|
+
worker.once('exit', onExit);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
39
63
|
function estimateItemBytes(item) {
|
|
40
64
|
if (typeof item !== 'object' || item === null)
|
|
41
65
|
return 0;
|
|
@@ -128,8 +152,21 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
|
|
|
128
152
|
const replaceWorker = async (workerIndex) => {
|
|
129
153
|
const worker = workers[workerIndex];
|
|
130
154
|
await worker?.terminate().catch(() => undefined);
|
|
131
|
-
if (
|
|
132
|
-
|
|
155
|
+
if (stopped)
|
|
156
|
+
return;
|
|
157
|
+
const replacement = new Worker(workerUrl);
|
|
158
|
+
try {
|
|
159
|
+
await waitForWorkerOnline(replacement);
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
await replacement.terminate().catch(() => undefined);
|
|
163
|
+
throw new Error(`Replacement worker ${workerIndex} failed to start: ${err instanceof Error ? err.message : String(err)}`);
|
|
164
|
+
}
|
|
165
|
+
if (stopped) {
|
|
166
|
+
await replacement.terminate().catch(() => undefined);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
workers[workerIndex] = replacement;
|
|
133
170
|
};
|
|
134
171
|
const fail = async (err) => {
|
|
135
172
|
poolBroken = true;
|
|
@@ -245,7 +282,7 @@ export const createWorkerPool = (workerUrl, poolSize, options) => {
|
|
|
245
282
|
await replaceWorker(workerIndex);
|
|
246
283
|
}
|
|
247
284
|
catch (err) {
|
|
248
|
-
void fail(err instanceof Error ? err : new Error(
|
|
285
|
+
void fail(err instanceof Error ? err : new Error(String(err)));
|
|
249
286
|
return;
|
|
250
287
|
}
|
|
251
288
|
finally {
|
package/dist/server/api.js
CHANGED
|
@@ -155,6 +155,7 @@ a.ext:hover{text-decoration:underline}
|
|
|
155
155
|
<div class="section-title">Endpoints</div>
|
|
156
156
|
<p class="endpoint"><a href="/api/info">/api/info</a> <span style="color:#5a5a70">— Server version & context</span></p>
|
|
157
157
|
<p class="endpoint"><a href="/api/repos">/api/repos</a> <span style="color:#5a5a70">— Indexed repositories</span></p>
|
|
158
|
+
<p class="endpoint"><code>/api/health</code> <span style="color:#5a5a70">— Docker/orchestrator healthcheck</span></p>
|
|
158
159
|
<p class="endpoint"><code>/api/heartbeat</code> <span style="color:#5a5a70">— SSE heartbeat</span></p>
|
|
159
160
|
<p class="endpoint"><code>/api/graph</code> <code>/api/query</code> <code>/api/search</code> <span style="color:#5a5a70">— Data</span></p>
|
|
160
161
|
<p class="endpoint"><code>/api/mcp</code> <span style="color:#5a5a70">— MCP over StreamableHTTP</span></p>
|
|
@@ -669,6 +670,12 @@ export const createServer = async (port, host = '127.0.0.1') => {
|
|
|
669
670
|
}
|
|
670
671
|
return found;
|
|
671
672
|
};
|
|
673
|
+
// Lightweight healthcheck for Docker/orchestrator probes (#1147).
|
|
674
|
+
// Returns immediately so container managers do not confuse a long-lived
|
|
675
|
+
// SSE stream with an unhealthy server.
|
|
676
|
+
app.get('/api/health', (_req, res) => {
|
|
677
|
+
res.json({ status: 'ok' });
|
|
678
|
+
});
|
|
672
679
|
// SSE heartbeat — clients connect to detect server liveness instantly.
|
|
673
680
|
// When the server shuts down, the TCP connection drops and the client's
|
|
674
681
|
// EventSource fires onerror immediately (no polling delay).
|
package/package.json
CHANGED