Node.js WebSocket reconnect loop eating up CPU on Genesys Notification API

Hey folks,

Running into a weird performance issue with my Node.js service that subscribes to the Genesys Cloud Notification API via WebSocket. The setup is pretty standard: grab a token, connect to wss://api.mypurecloud.com/v2/analytics/events, and start listening for event data. The connection works fine initially, but whenever the server drops the connection (usually after an idle timeout or a brief network blip), my reconnect logic goes haywire.

I’m using the standard ws library. Here’s the gist of my reconnect handler:

ws.on('close', (code, reason) => {
 console.log(`Connection closed: ${code}`);
 if (code !== 1000) {
 // Attempt to reconnect
 setTimeout(() => {
 connect(); 
 }, 1000);
 }
});

The problem is the connect() function. It fetches a new OAuth token before establishing the socket. If the token fetch fails or hangs, I’m not handling that error gracefully, and the timeout keeps firing. I end up with hundreds of pending promises stacking up, which spikes the CPU to 100% and eventually crashes the process. It feels like a race condition between the token refresh and the socket open event.

I tried adding a simple isReconnecting flag to prevent multiple simultaneous attempts, but that feels like a band-aid. Is there a better pattern for handling these reconnection storms? I’ve seen some folks mention using Exponential Backoff, but I’m not sure how to integrate that cleanly with the async token refresh step without making the code a mess.

Also, is there a specific close code I should be watching for that indicates a server-side maintenance window versus a client-side error? The docs are a bit vague on which codes warrant an immediate retry versus a longer wait.

Here’s the error log snippet I’m seeing before the crash:

(node:1234) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 error listeners added to [Socket].

Any ideas on how to structure this more robustly?