@mjasnikovs/pi-task 0.16.0 → 0.16.1
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/remote/server.js +24 -0
- package/package.json +1 -1
package/dist/remote/server.js
CHANGED
|
@@ -109,14 +109,38 @@ export async function startServer(onMessage, getHtml) {
|
|
|
109
109
|
}
|
|
110
110
|
});
|
|
111
111
|
const wss = new WebSocketServer({ server: httpServer, path: '/ws' });
|
|
112
|
+
// Track every accepted TCP socket so stop() can forcibly destroy lingering
|
|
113
|
+
// keep-alive / WebSocket connections. Without this, httpServer.close() only
|
|
114
|
+
// stops accepting new connections and waits for existing ones to drain — an
|
|
115
|
+
// open browser tab never drains, so the listening server and its sockets
|
|
116
|
+
// stay as active event-loop handles forever. In headless print mode the host
|
|
117
|
+
// exits by natural event-loop drain (it sets process.exitCode and returns,
|
|
118
|
+
// with no process.exit()), so these lingering handles keep the pi process
|
|
119
|
+
// alive indefinitely — which blocks `docker stop` / OS shutdown until the
|
|
120
|
+
// SIGKILL grace timeout fires. A/B-proven: terminating clients + destroying
|
|
121
|
+
// sockets here makes the loop drain in ~2ms instead of never.
|
|
122
|
+
const sockets = new Set();
|
|
123
|
+
httpServer.on('connection', s => {
|
|
124
|
+
sockets.add(s);
|
|
125
|
+
s.on('close', () => sockets.delete(s));
|
|
126
|
+
});
|
|
112
127
|
const handle = {
|
|
113
128
|
port,
|
|
114
129
|
ip,
|
|
115
130
|
ips,
|
|
116
131
|
onFirstConnect: null,
|
|
117
132
|
stop() {
|
|
133
|
+
// Terminate WebSocket clients (immediate close, no drain), then
|
|
134
|
+
// destroy any remaining raw sockets, then close the servers so the
|
|
135
|
+
// event loop has no lingering handles holding the process open.
|
|
136
|
+
for (const ws of wss.clients)
|
|
137
|
+
ws.terminate();
|
|
118
138
|
wss.close();
|
|
139
|
+
for (const s of sockets)
|
|
140
|
+
s.destroy();
|
|
141
|
+
sockets.clear();
|
|
119
142
|
httpServer.close();
|
|
143
|
+
httpServer.closeAllConnections?.();
|
|
120
144
|
}
|
|
121
145
|
};
|
|
122
146
|
wss.on('connection', ws => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mjasnikovs/pi-task",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.1",
|
|
4
4
|
"description": "Deterministic spec-orchestration for local models, with a bundled real-time remote web view and web/docs/fetch/worker subagent tools.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|