grepmax 0.7.31 → 0.7.33
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.
package/dist/commands/serve.js
CHANGED
|
@@ -380,6 +380,7 @@ exports.serve = new commander_1.Command("serve")
|
|
|
380
380
|
// Ensure we exit if server fails to start
|
|
381
381
|
process.exit(1);
|
|
382
382
|
});
|
|
383
|
+
server.setTimeout(60000); // 60s request timeout
|
|
383
384
|
server.listen(port, () => {
|
|
384
385
|
const address = server.address();
|
|
385
386
|
const actualPort = typeof address === "object" && address ? address.port : port;
|
|
@@ -77,6 +77,8 @@ const DEBOUNCE_MS = 2000;
|
|
|
77
77
|
const FTS_REBUILD_INTERVAL_MS = 5 * 60 * 1000;
|
|
78
78
|
function startWatcher(opts) {
|
|
79
79
|
const { projectRoot, vectorDb, metaCache, dataDir, onReindex } = opts;
|
|
80
|
+
const projectName = path.basename(projectRoot);
|
|
81
|
+
const wtag = `watch:${projectName}`;
|
|
80
82
|
const pending = new Map();
|
|
81
83
|
const retryCount = new Map();
|
|
82
84
|
let debounceTimer = null;
|
|
@@ -96,14 +98,19 @@ function startWatcher(opts) {
|
|
|
96
98
|
binaryInterval: 10000,
|
|
97
99
|
});
|
|
98
100
|
watcher.on("error", (err) => {
|
|
99
|
-
console.error(
|
|
101
|
+
console.error(`[${wtag}] Watcher error:`, err);
|
|
100
102
|
});
|
|
101
103
|
const scheduleBatch = () => {
|
|
102
104
|
if (debounceTimer)
|
|
103
105
|
clearTimeout(debounceTimer);
|
|
104
106
|
debounceTimer = setTimeout(() => processBatch(), DEBOUNCE_MS);
|
|
105
107
|
};
|
|
106
|
-
const
|
|
108
|
+
const taskTimeoutMs = (() => {
|
|
109
|
+
var _a;
|
|
110
|
+
const fromEnv = Number.parseInt((_a = process.env.GMAX_WORKER_TASK_TIMEOUT_MS) !== null && _a !== void 0 ? _a : "", 10);
|
|
111
|
+
return Number.isFinite(fromEnv) && fromEnv > 0 ? fromEnv : 120000;
|
|
112
|
+
})();
|
|
113
|
+
const BATCH_TIMEOUT_MS = Math.max(Math.ceil(taskTimeoutMs * 1.5), 120000);
|
|
107
114
|
const processBatch = () => __awaiter(this, void 0, void 0, function* () {
|
|
108
115
|
var _a;
|
|
109
116
|
if (closed || processing || pending.size === 0)
|
|
@@ -111,13 +118,13 @@ function startWatcher(opts) {
|
|
|
111
118
|
processing = true;
|
|
112
119
|
const batchTimeout = setTimeout(() => {
|
|
113
120
|
if (processing) {
|
|
114
|
-
console.error(
|
|
121
|
+
console.error(`[${wtag}] Batch processing timed out after 120s, resetting`);
|
|
115
122
|
processing = false;
|
|
116
123
|
}
|
|
117
124
|
}, BATCH_TIMEOUT_MS);
|
|
118
125
|
const batch = new Map(pending);
|
|
119
126
|
pending.clear();
|
|
120
|
-
(0, logger_1.log)(
|
|
127
|
+
(0, logger_1.log)(wtag, `Processing ${batch.size} changed files`);
|
|
121
128
|
const start = Date.now();
|
|
122
129
|
let reindexed = 0;
|
|
123
130
|
const changedIds = [];
|
|
@@ -188,7 +195,11 @@ function startWatcher(opts) {
|
|
|
188
195
|
reindexed++;
|
|
189
196
|
}
|
|
190
197
|
else {
|
|
191
|
-
console.error(`[
|
|
198
|
+
console.error(`[${wtag}] Failed to process ${absPath}:`, err);
|
|
199
|
+
if (!pool.isHealthy()) {
|
|
200
|
+
console.error(`[${wtag}] Worker pool unhealthy, aborting batch`);
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
192
203
|
}
|
|
193
204
|
}
|
|
194
205
|
}
|
|
@@ -216,10 +227,11 @@ function startWatcher(opts) {
|
|
|
216
227
|
finally {
|
|
217
228
|
yield lock.release();
|
|
218
229
|
}
|
|
230
|
+
const duration = Date.now() - start;
|
|
219
231
|
if (reindexed > 0) {
|
|
220
|
-
const duration = Date.now() - start;
|
|
221
232
|
onReindex === null || onReindex === void 0 ? void 0 : onReindex(reindexed, duration);
|
|
222
233
|
}
|
|
234
|
+
(0, logger_1.log)(wtag, `Batch complete: ${batch.size} files, ${reindexed} reindexed (${(duration / 1000).toFixed(1)}s)`);
|
|
223
235
|
consecutiveLockFailures = 0;
|
|
224
236
|
for (const absPath of batch.keys()) {
|
|
225
237
|
retryCount.delete(absPath);
|
|
@@ -230,7 +242,7 @@ function startWatcher(opts) {
|
|
|
230
242
|
if (isLockError) {
|
|
231
243
|
consecutiveLockFailures++;
|
|
232
244
|
}
|
|
233
|
-
console.error(
|
|
245
|
+
console.error(`[${wtag}] Batch processing failed:`, err);
|
|
234
246
|
let dropped = 0;
|
|
235
247
|
for (const [absPath, event] of batch) {
|
|
236
248
|
const count = ((_a = retryCount.get(absPath)) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
@@ -244,7 +256,7 @@ function startWatcher(opts) {
|
|
|
244
256
|
}
|
|
245
257
|
}
|
|
246
258
|
if (dropped > 0) {
|
|
247
|
-
console.warn(`[
|
|
259
|
+
console.warn(`[${wtag}] Dropped ${dropped} file(s) after ${MAX_RETRIES} failed retries`);
|
|
248
260
|
}
|
|
249
261
|
if (pending.size > 0) {
|
|
250
262
|
const backoffMs = Math.min(DEBOUNCE_MS * Math.pow(2, consecutiveLockFailures), 30000);
|
|
@@ -320,7 +332,7 @@ function startWatcher(opts) {
|
|
|
320
332
|
yield vectorDb.createFTSIndex();
|
|
321
333
|
}
|
|
322
334
|
catch (err) {
|
|
323
|
-
console.error(
|
|
335
|
+
console.error(`[${wtag}] FTS rebuild failed:`, err);
|
|
324
336
|
}
|
|
325
337
|
}), FTS_REBUILD_INTERVAL_MS);
|
|
326
338
|
ftsInterval.unref();
|
|
@@ -95,13 +95,9 @@ function postJSON(path, body) {
|
|
|
95
95
|
/**
|
|
96
96
|
* Check if MLX server is reachable. Caches result for CHECK_INTERVAL_MS.
|
|
97
97
|
*/
|
|
98
|
-
function
|
|
98
|
+
function checkHealth() {
|
|
99
99
|
return __awaiter(this, void 0, void 0, function* () {
|
|
100
|
-
|
|
101
|
-
if (mlxAvailable !== null && now - lastCheck < CHECK_INTERVAL_MS) {
|
|
102
|
-
return mlxAvailable;
|
|
103
|
-
}
|
|
104
|
-
const result = yield new Promise((resolve) => {
|
|
100
|
+
return new Promise((resolve) => {
|
|
105
101
|
const req = http.get({ hostname: MLX_HOST, port: MLX_PORT, path: "/health", timeout: 2000 }, (res) => {
|
|
106
102
|
res.resume();
|
|
107
103
|
resolve(res.statusCode === 200);
|
|
@@ -112,6 +108,20 @@ function isMlxUp() {
|
|
|
112
108
|
resolve(false);
|
|
113
109
|
});
|
|
114
110
|
});
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
function isMlxUp() {
|
|
114
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
115
|
+
const now = Date.now();
|
|
116
|
+
if (mlxAvailable !== null && now - lastCheck < CHECK_INTERVAL_MS) {
|
|
117
|
+
return mlxAvailable;
|
|
118
|
+
}
|
|
119
|
+
let result = yield checkHealth();
|
|
120
|
+
// On first check (cold start), retry once after 3s — server may still be loading
|
|
121
|
+
if (!result && mlxAvailable === null) {
|
|
122
|
+
yield new Promise((r) => setTimeout(r, 3000));
|
|
123
|
+
result = yield checkHealth();
|
|
124
|
+
}
|
|
115
125
|
mlxAvailable = result;
|
|
116
126
|
lastCheck = now;
|
|
117
127
|
return result;
|
package/dist/lib/workers/pool.js
CHANGED
package/package.json
CHANGED