From 0757f6819e0bcc6d56cfab7f370cad4c3480a8a2 Mon Sep 17 00:00:00 2001 From: kiryazovi-redis Date: Sat, 18 Jul 2026 16:16:54 +0300 Subject: [PATCH] test(scenario): tolerate at-least-once duplicates during pub/sub migrate handoff The OSS smart-client-handoff scenario subscribes the new pub/sub node before destroying the old one, so a broadcast message can be delivered by both connections during the overlap window (intentional at-least-once). The during-migrate assertion `received <= sent` encoded an at-most-once invariant that this handoff deliberately does not provide, producing spurious `received (N) should be <= sent (M)` failures. Assert instead that delivery continued through the handoff; the strict, loss-free `received === sent` check after migration is unchanged. --- .../smart-client-handoffs-oss.e2e.ts | 80 +++++++++++++++---- 1 file changed, 64 insertions(+), 16 deletions(-) diff --git a/packages/client/lib/tests/test-scenario/smart-client-handoffs-oss.e2e.ts b/packages/client/lib/tests/test-scenario/smart-client-handoffs-oss.e2e.ts index bfad16b1039..a29f4d9a040 100644 --- a/packages/client/lib/tests/test-scenario/smart-client-handoffs-oss.e2e.ts +++ b/packages/client/lib/tests/test-scenario/smart-client-handoffs-oss.e2e.ts @@ -284,9 +284,15 @@ const KEYS = [ await publishPromise; for (const channel of KEYS) { + // During the migrate handoff the client subscribes the new pub/sub + // node before destroying the old one, so a message can be delivered + // by both connections during the overlap (intentional at-least-once). + // Duplicates are therefore expected; assert only that delivery kept + // flowing through the handoff. Exact, loss-free delivery is verified + // strictly after migration below. assert.ok( - stats[channel].received <= stats[channel].sent, - `Channel ${channel}: received (${stats[channel].received}) should be <= sent (${stats[channel].sent}) during migrate` + stats[channel].received > 0, + `Channel ${channel}: should keep receiving messages during migrate (received ${stats[channel].received}, sent ${stats[channel].sent})` ); } @@ -364,9 +370,15 @@ const KEYS = [ await publishPromise; for (const channel of KEYS) { + // During the migrate handoff the client subscribes the new pub/sub + // node before destroying the old one, so a message can be delivered + // by both connections during the overlap (intentional at-least-once). + // Duplicates are therefore expected; assert only that delivery kept + // flowing through the handoff. Exact, loss-free delivery is verified + // strictly after migration below. assert.ok( - stats[channel].received <= stats[channel].sent, - `Channel ${channel}: received (${stats[channel].received}) should be <= sent (${stats[channel].sent}) during migrate` + stats[channel].received > 0, + `Channel ${channel}: should keep receiving messages during migrate (received ${stats[channel].received}, sent ${stats[channel].sent})` ); } @@ -581,9 +593,15 @@ const KEYS = [ await publishPromise; for (const channel of KEYS) { + // During the migrate handoff the client subscribes the new pub/sub + // node before destroying the old one, so a message can be delivered + // by both connections during the overlap (intentional at-least-once). + // Duplicates are therefore expected; assert only that delivery kept + // flowing through the handoff. Exact, loss-free delivery is verified + // strictly after migration below. assert.ok( - stats[channel].received <= stats[channel].sent, - `Channel ${channel}: received (${stats[channel].received}) should be <= sent (${stats[channel].sent}) during migrate` + stats[channel].received > 0, + `Channel ${channel}: should keep receiving messages during migrate (received ${stats[channel].received}, sent ${stats[channel].sent})` ); } @@ -661,9 +679,15 @@ const KEYS = [ await publishPromise; for (const channel of KEYS) { + // During the migrate handoff the client subscribes the new pub/sub + // node before destroying the old one, so a message can be delivered + // by both connections during the overlap (intentional at-least-once). + // Duplicates are therefore expected; assert only that delivery kept + // flowing through the handoff. Exact, loss-free delivery is verified + // strictly after migration below. assert.ok( - stats[channel].received <= stats[channel].sent, - `Channel ${channel}: received (${stats[channel].received}) should be <= sent (${stats[channel].sent}) during migrate` + stats[channel].received > 0, + `Channel ${channel}: should keep receiving messages during migrate (received ${stats[channel].received}, sent ${stats[channel].sent})` ); } @@ -879,9 +903,15 @@ const KEYS = [ await publishPromise; for (const channel of KEYS) { + // During the migrate handoff the client subscribes the new pub/sub + // node before destroying the old one, so a message can be delivered + // by both connections during the overlap (intentional at-least-once). + // Duplicates are therefore expected; assert only that delivery kept + // flowing through the handoff. Exact, loss-free delivery is verified + // strictly after migration below. assert.ok( - stats[channel].received <= stats[channel].sent, - `Channel ${channel}: received (${stats[channel].received}) should be <= sent (${stats[channel].sent}) during migrate` + stats[channel].received > 0, + `Channel ${channel}: should keep receiving messages during migrate (received ${stats[channel].received}, sent ${stats[channel].sent})` ); } @@ -959,9 +989,15 @@ const KEYS = [ await publishPromise; for (const channel of KEYS) { + // During the migrate handoff the client subscribes the new pub/sub + // node before destroying the old one, so a message can be delivered + // by both connections during the overlap (intentional at-least-once). + // Duplicates are therefore expected; assert only that delivery kept + // flowing through the handoff. Exact, loss-free delivery is verified + // strictly after migration below. assert.ok( - stats[channel].received <= stats[channel].sent, - `Channel ${channel}: received (${stats[channel].received}) should be <= sent (${stats[channel].sent}) during migrate` + stats[channel].received > 0, + `Channel ${channel}: should keep receiving messages during migrate (received ${stats[channel].received}, sent ${stats[channel].sent})` ); } @@ -1175,9 +1211,15 @@ const KEYS = [ await publishPromise; for (const channel of KEYS) { + // During the migrate handoff the client subscribes the new pub/sub + // node before destroying the old one, so a message can be delivered + // by both connections during the overlap (intentional at-least-once). + // Duplicates are therefore expected; assert only that delivery kept + // flowing through the handoff. Exact, loss-free delivery is verified + // strictly after migration below. assert.ok( - stats[channel].received <= stats[channel].sent, - `Channel ${channel}: received (${stats[channel].received}) should be <= sent (${stats[channel].sent}) during migrate` + stats[channel].received > 0, + `Channel ${channel}: should keep receiving messages during migrate (received ${stats[channel].received}, sent ${stats[channel].sent})` ); } @@ -1255,9 +1297,15 @@ const KEYS = [ await publishPromise; for (const channel of KEYS) { + // During the migrate handoff the client subscribes the new pub/sub + // node before destroying the old one, so a message can be delivered + // by both connections during the overlap (intentional at-least-once). + // Duplicates are therefore expected; assert only that delivery kept + // flowing through the handoff. Exact, loss-free delivery is verified + // strictly after migration below. assert.ok( - stats[channel].received <= stats[channel].sent, - `Channel ${channel}: received (${stats[channel].received}) should be <= sent (${stats[channel].sent}) during migrate` + stats[channel].received > 0, + `Channel ${channel}: should keep receiving messages during migrate (received ${stats[channel].received}, sent ${stats[channel].sent})` ); }