@pylonsync/sync 0.3.180 → 0.3.182
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/package.json +1 -1
- package/src/index.ts +17 -13
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1160,18 +1160,22 @@ export class SyncEngine {
|
|
|
1160
1160
|
this.reconnectAttempts = 0;
|
|
1161
1161
|
this.wsStableTimer = null;
|
|
1162
1162
|
}, 5_000);
|
|
1163
|
-
// Client-side keepalive ping. The server's per-client
|
|
1164
|
-
// thread blocks on
|
|
1165
|
-
//
|
|
1166
|
-
//
|
|
1167
|
-
//
|
|
1168
|
-
//
|
|
1169
|
-
//
|
|
1170
|
-
//
|
|
1171
|
-
//
|
|
1172
|
-
//
|
|
1173
|
-
//
|
|
1174
|
-
// the mutex
|
|
1163
|
+
// Client-side keepalive ping at 200ms. The server's per-client
|
|
1164
|
+
// reader thread blocks synchronously on `ws.read()` and holds the
|
|
1165
|
+
// per-client mutex for the duration of the call. On the dedicated
|
|
1166
|
+
// `:port+1` listener that block is bounded by a 200ms TCP read
|
|
1167
|
+
// timeout (`stream.set_read_timeout`), so the broadcaster gets a
|
|
1168
|
+
// window every 200ms. The HTTP-multiplexed `/api/sync/ws` path
|
|
1169
|
+
// goes through tiny_http's `CustomStream`, which doesn't expose
|
|
1170
|
+
// the underlying TcpStream, so we can't set a timeout there.
|
|
1171
|
+
// These periodic JSON pings give the broadcaster the same 200ms
|
|
1172
|
+
// window by causing the read to return (the server treats
|
|
1173
|
+
// unknown `type` values as no-ops; the side effect is releasing
|
|
1174
|
+
// the mutex between iterations). Browsers don't expose WS-level
|
|
1175
|
+
// PING frames at the application layer, so we send a Text frame.
|
|
1176
|
+
// Tradeoff: ~5 inbound frames/sec/client of background traffic
|
|
1177
|
+
// for sub-second broadcast latency — worth it for the demo
|
|
1178
|
+
// experience and idle tabs alike.
|
|
1175
1179
|
if (this.pingTimer) clearInterval(this.pingTimer);
|
|
1176
1180
|
this.pingTimer = setInterval(() => {
|
|
1177
1181
|
if (this.ws?.readyState !== WebSocket.OPEN) return;
|
|
@@ -1180,7 +1184,7 @@ export class SyncEngine {
|
|
|
1180
1184
|
} catch {
|
|
1181
1185
|
// ignore — onclose will trigger reconnect
|
|
1182
1186
|
}
|
|
1183
|
-
},
|
|
1187
|
+
}, 200);
|
|
1184
1188
|
// Re-send any active CRDT subscriptions across the new socket.
|
|
1185
1189
|
// The server purged them on disconnect (`unsubscribe_all`), so
|
|
1186
1190
|
// without this resync a tab that was subscribed before a network
|