Skip to content

Commit 39bf2fc

Browse files
ggazzoclaude
andcommitted
fix(sdk): revert to full fire('reset') on SDK reconnect
Surgical onReconnect-only call broke message-actions, report-message, and e2ee-encryption-decryption — those tests fire methods exactly when the SDK socket churns from a force-logout cycle, and without the full reset's _callOnReconnectAndSendAppropriateOutstandingMethods step the methods stay marked sentMessage=true forever. The bridge's async catch already absorbs the "method result but no methods outstanding" warnings that the resent blocks generate, so the noise is harmless. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 3048858 commit 39bf2fc

1 file changed

Lines changed: 17 additions & 19 deletions

File tree

apps/meteor/client/meteor/overrides/stubMeteorStream.ts

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { DDP } from 'meteor/ddp';
21
import { DDPCommon } from 'meteor/ddp-common';
32
import { Meteor } from 'meteor/meteor';
43
import { Tracker } from 'meteor/tracker';
@@ -216,18 +215,22 @@ queueMicrotask(() => {
216215
// When the underlying SDK socket reconnects (e.g. after a server-side
217216
// ws.terminate from force-logout in microservices), Meteor's connection sees
218217
// no transport event because the stub keeps reporting 'connected'. As a
219-
// result, Meteor's normal reconnect machinery never fires the per-call
220-
// _reconnectStopper that callLoginMethod registers — the one that retries
221-
// login with the latest stored token and calls makeClientLoggedOut on
222-
// failure (accounts_client.js:292). The user is left with stale credentials.
218+
// result, Meteor's normal reconnect machinery — `_streamHandlers.onReset` →
219+
// `_callOnReconnectAndSendAppropriateOutstandingMethods` → DDP.onReconnect
220+
// callbacks → the per-call `_reconnectStopper` that retries login with the
221+
// latest stored token (and calls `makeClientLoggedOut` on failure) — never
222+
// fires. The user is left with stale credentials.
223223
//
224-
// Invoke the DDP.onReconnect callbacks directly on every subsequent SDK
225-
// 'connected' event so accounts-base's stopper runs. Skip the full
226-
// _streamHandlers.onReset path: re-sending the outstanding method blocks
227-
// confuses Meteor (those methods already completed on the previous SDK
228-
// session and re-feeding them through the bridge yields "method result but
229-
// no methods outstanding"); and DDPSDK already re-subscribes its own
230-
// publications on reconnect so we don't need _resendSubscriptions either.
224+
// Fire `reset` on every subsequent SDK 'connected' event so accounts-base's
225+
// onReconnect callback retries login with whatever's currently in
226+
// localStorage AND so methods that were sent but not yet completed get
227+
// resent on the new session (skipping this part wedges tests that fire a
228+
// method right when the SDK socket churns: message-actions / report-message
229+
// / e2ee-encryption-decryption all timed out without it). The first connect
230+
// is handled by the queueMicrotask above; skip it here. The "method result
231+
// but no methods outstanding" warnings that the resent blocks generate are
232+
// caught and suppressed by the bridge's async catch in
233+
// ddpSdkCollectionBridge.
231234
const sdk = getDdpSdk();
232235
let firstConnectHandled = false;
233236
sdk.connection.on('connected', () => {
@@ -236,13 +239,8 @@ sdk.connection.on('connected', () => {
236239
return;
237240
}
238241
try {
239-
const hook = (DDP as unknown as { _reconnectHook?: { each(cb: (callback: (conn: unknown) => unknown) => boolean): void } })
240-
._reconnectHook;
241-
hook?.each((callback) => {
242-
callback(Meteor.connection);
243-
return true;
244-
});
242+
fire('reset');
245243
} catch (err) {
246-
console.warn('[stubMeteorStream] onReconnect callbacks on SDK reconnect failed', err);
244+
console.warn('[stubMeteorStream] reset on SDK reconnect failed', err);
247245
}
248246
});

0 commit comments

Comments
 (0)