Skip to content

Commit 9e3ccd3

Browse files
authored
fix: let the provider decide when to reuse an existing subscription ID (#2929)
Fix for #2926 Signed-off-by: Giuseppe Bertone <[email protected]>
1 parent 5018b23 commit 9e3ccd3

File tree

3 files changed

+47
-5
lines changed

3 files changed

+47
-5
lines changed

docs/configuration.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ Unless you need to set a non-default value, it is recommended to only populate o
123123
| `WS_CACHE_TTL` | "20000" | The time to live for cached entries. |
124124
| `WS_NEW_HEADS_ENABLED`. | "true" | Enables subscriptions for the latest blocks, `newHeads`. |
125125
| `WS_PING_INTERVAL` | "100000" | Interval between ping messages. Set to `0` to disable pinger. |
126+
| `WS_SAME_SUB_FOR_SAME_EVENT` | "true" | The relay will return the same subscription ID when a client subscribes to the same event multiple times using a single connection. When set to false, the relay will always create a new subscription ID for each `eth_subscribe' request. |
126127

127128
## Sample for connecting to Hedera Environments
128129

packages/relay/src/lib/subscriptionController.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export class SubscriptionController {
4141
private cache;
4242
private activeSubscriptionHistogram: Histogram;
4343
private resultsSentToSubscribersCounter: Counter;
44+
private useTheSameSubscriptionForTheSameEvent: boolean;
4445

4546
constructor(poller: Poller, logger: Logger, register: Registry) {
4647
this.poller = poller;
@@ -76,6 +77,9 @@ export class SubscriptionController {
7677
registers: [register],
7778
labelNames: ['subId', 'tag'],
7879
});
80+
81+
// Default: true
82+
this.useTheSameSubscriptionForTheSameEvent = process.env.WS_SAME_SUB_FOR_SAME_EVENT?.toLowerCase() !== 'false';
7983
}
8084

8185
createHash(data) {
@@ -99,11 +103,13 @@ export class SubscriptionController {
99103
this.subscriptions[tag] = [];
100104
}
101105

102-
// Check if the connection is already subscribed to this event
103-
const existingSub = this.subscriptions[tag].find((sub) => sub.connection.id === connection.id);
104-
if (existingSub) {
105-
this.logger.debug(`Connection ${connection.id}: Attempting to subscribe to ${tag}; already subscribed`);
106-
return existingSub.subscriptionId;
106+
if (this.useTheSameSubscriptionForTheSameEvent) {
107+
// Check if the connection is already subscribed to this event
108+
const existingSub = this.subscriptions[tag].find((sub) => sub.connection.id === connection.id);
109+
if (existingSub) {
110+
this.logger.debug(`Connection ${connection.id}: Attempting to subscribe to ${tag}; already subscribed`);
111+
return existingSub.subscriptionId;
112+
}
107113
}
108114

109115
const subId = this.generateId();

packages/relay/tests/lib/subscriptionController.spec.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,4 +263,39 @@ describe('subscriptionController', async function () {
263263
subscriptionController.unsubscribe(wsConnection, subId);
264264
subscriptionController.unsubscribe(wsConnection, subId2);
265265
});
266+
267+
describe('With WS_SAME_SUB_FOR_SAME_EVENT == `false`', async function () {
268+
let originalEnv;
269+
let originalSubscriptionController;
270+
271+
before(() => {
272+
originalEnv = process.env.WS_SAME_SUB_FOR_SAME_EVENT;
273+
originalSubscriptionController = subscriptionController;
274+
275+
process.env.WS_SAME_SUB_FOR_SAME_EVENT = 'false';
276+
const registry = new Registry();
277+
poller = new Poller(ethImpl, logger, registry);
278+
subscriptionController = new SubscriptionController(poller, logger, registry);
279+
});
280+
281+
after(() => {
282+
process.env.WS_SAME_SUB_FOR_SAME_EVENT = originalEnv;
283+
subscriptionController = originalSubscriptionController;
284+
});
285+
286+
it('Subscribing to the same event and filters should return different subscription id', async function () {
287+
const connectionId = '7';
288+
const wsConnection = new MockWsConnection(connectionId);
289+
const tag1 = {
290+
event: 'logs',
291+
filters: { topics: ['0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'] },
292+
};
293+
const subId = subscriptionController.subscribe(wsConnection, tag1.event);
294+
const subId2 = subscriptionController.subscribe(wsConnection, tag1.event);
295+
296+
expect(subId).to.be.not.eq(subId2);
297+
subscriptionController.unsubscribe(wsConnection, subId);
298+
subscriptionController.unsubscribe(wsConnection, subId2);
299+
});
300+
});
266301
});

0 commit comments

Comments
 (0)