grepmax 0.14.8 → 0.14.9
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.
|
@@ -146,20 +146,77 @@ class Daemon {
|
|
|
146
146
|
}
|
|
147
147
|
throw err;
|
|
148
148
|
}
|
|
149
|
-
// 2.
|
|
149
|
+
// 2. Stale socket cleanup + start socket server EARLY.
|
|
150
|
+
// The socket must be listening before the PID file is written so that
|
|
151
|
+
// other daemons checking isDaemonRunning() never see a PID for a process
|
|
152
|
+
// that can't respond to pings. Without this, the slow initialization
|
|
153
|
+
// steps below (LanceDB, MLX, project watchers) create a window where
|
|
154
|
+
// new daemons kill this one as "unresponsive".
|
|
155
|
+
try {
|
|
156
|
+
fs.unlinkSync(config_1.PATHS.daemonSocket);
|
|
157
|
+
}
|
|
158
|
+
catch (_b) { }
|
|
159
|
+
this.server = net.createServer((conn) => {
|
|
160
|
+
(0, logger_1.debug)("daemon", "client connected");
|
|
161
|
+
let buf = "";
|
|
162
|
+
conn.on("data", (chunk) => {
|
|
163
|
+
buf += chunk.toString();
|
|
164
|
+
if (buf.length > 1000000) {
|
|
165
|
+
conn.destroy();
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const nl = buf.indexOf("\n");
|
|
169
|
+
if (nl === -1)
|
|
170
|
+
return;
|
|
171
|
+
const line = buf.slice(0, nl);
|
|
172
|
+
buf = buf.slice(nl + 1);
|
|
173
|
+
let cmd;
|
|
174
|
+
try {
|
|
175
|
+
cmd = JSON.parse(line);
|
|
176
|
+
}
|
|
177
|
+
catch (_a) {
|
|
178
|
+
conn.write(`${JSON.stringify({ ok: false, error: "invalid JSON" })}\n`);
|
|
179
|
+
conn.end();
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
(0, ipc_handler_1.handleCommand)(this, cmd, conn).then((resp) => {
|
|
183
|
+
// null means the handler is managing the connection (streaming)
|
|
184
|
+
if (resp !== null) {
|
|
185
|
+
conn.write(`${JSON.stringify(resp)}\n`);
|
|
186
|
+
conn.end();
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
conn.on("error", () => { });
|
|
191
|
+
});
|
|
192
|
+
yield new Promise((resolve, reject) => {
|
|
193
|
+
this.server.on("error", (err) => {
|
|
194
|
+
const code = err.code;
|
|
195
|
+
if (code === "EADDRINUSE") {
|
|
196
|
+
console.error("[daemon] Socket already in use");
|
|
197
|
+
reject(err);
|
|
198
|
+
}
|
|
199
|
+
else if (code === "EOPNOTSUPP") {
|
|
200
|
+
console.error("[daemon] Filesystem does not support Unix sockets");
|
|
201
|
+
process.exitCode = 2;
|
|
202
|
+
reject(err);
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
reject(err);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
this.server.listen(config_1.PATHS.daemonSocket, () => resolve());
|
|
209
|
+
});
|
|
210
|
+
// 3. Write PID file AFTER socket is listening — ensures any process that
|
|
211
|
+
// reads the PID can immediately ping this daemon and get a response.
|
|
212
|
+
fs.writeFileSync(config_1.PATHS.daemonPidFile, String(process.pid));
|
|
213
|
+
// 4. Kill existing per-project watchers
|
|
150
214
|
const existing = (0, watcher_store_1.listWatchers)();
|
|
151
215
|
for (const w of existing) {
|
|
152
216
|
console.log(`[daemon] Taking over from per-project watcher (PID: ${w.pid}, ${path.basename(w.projectRoot)})`);
|
|
153
217
|
yield (0, process_1.killProcess)(w.pid);
|
|
154
218
|
(0, watcher_store_1.unregisterWatcher)(w.pid);
|
|
155
219
|
}
|
|
156
|
-
// 3. Write PID file (informational only — lock is the real guard)
|
|
157
|
-
fs.writeFileSync(config_1.PATHS.daemonPidFile, String(process.pid));
|
|
158
|
-
// 4. Stale socket cleanup
|
|
159
|
-
try {
|
|
160
|
-
fs.unlinkSync(config_1.PATHS.daemonSocket);
|
|
161
|
-
}
|
|
162
|
-
catch (_b) { }
|
|
163
220
|
// 5. Open shared resources
|
|
164
221
|
try {
|
|
165
222
|
fs.mkdirSync(config_1.PATHS.cacheDir, { recursive: true });
|
|
@@ -222,58 +279,6 @@ class Daemon {
|
|
|
222
279
|
this.shutdown();
|
|
223
280
|
}
|
|
224
281
|
}, HEARTBEAT_INTERVAL_MS);
|
|
225
|
-
// 11. Socket server
|
|
226
|
-
this.server = net.createServer((conn) => {
|
|
227
|
-
(0, logger_1.debug)("daemon", "client connected");
|
|
228
|
-
let buf = "";
|
|
229
|
-
conn.on("data", (chunk) => {
|
|
230
|
-
buf += chunk.toString();
|
|
231
|
-
if (buf.length > 1000000) {
|
|
232
|
-
conn.destroy();
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
const nl = buf.indexOf("\n");
|
|
236
|
-
if (nl === -1)
|
|
237
|
-
return;
|
|
238
|
-
const line = buf.slice(0, nl);
|
|
239
|
-
buf = buf.slice(nl + 1);
|
|
240
|
-
let cmd;
|
|
241
|
-
try {
|
|
242
|
-
cmd = JSON.parse(line);
|
|
243
|
-
}
|
|
244
|
-
catch (_a) {
|
|
245
|
-
conn.write(`${JSON.stringify({ ok: false, error: "invalid JSON" })}\n`);
|
|
246
|
-
conn.end();
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
(0, ipc_handler_1.handleCommand)(this, cmd, conn).then((resp) => {
|
|
250
|
-
// null means the handler is managing the connection (streaming)
|
|
251
|
-
if (resp !== null) {
|
|
252
|
-
conn.write(`${JSON.stringify(resp)}\n`);
|
|
253
|
-
conn.end();
|
|
254
|
-
}
|
|
255
|
-
});
|
|
256
|
-
});
|
|
257
|
-
conn.on("error", () => { });
|
|
258
|
-
});
|
|
259
|
-
yield new Promise((resolve, reject) => {
|
|
260
|
-
this.server.on("error", (err) => {
|
|
261
|
-
const code = err.code;
|
|
262
|
-
if (code === "EADDRINUSE") {
|
|
263
|
-
console.error("[daemon] Socket already in use");
|
|
264
|
-
reject(err);
|
|
265
|
-
}
|
|
266
|
-
else if (code === "EOPNOTSUPP") {
|
|
267
|
-
console.error("[daemon] Filesystem does not support Unix sockets");
|
|
268
|
-
process.exitCode = 2;
|
|
269
|
-
reject(err);
|
|
270
|
-
}
|
|
271
|
-
else {
|
|
272
|
-
reject(err);
|
|
273
|
-
}
|
|
274
|
-
});
|
|
275
|
-
this.server.listen(config_1.PATHS.daemonSocket, () => resolve());
|
|
276
|
-
});
|
|
277
282
|
console.log(`[daemon] Started (PID: ${process.pid}, ${this.processors.size} projects)`);
|
|
278
283
|
});
|
|
279
284
|
}
|
package/package.json
CHANGED