Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevented reconnect #165

Open
yaroslavputria opened this issue Sep 3, 2021 · 7 comments
Open

Prevented reconnect #165

yaroslavputria opened this issue Sep 3, 2021 · 7 comments

Comments

@yaroslavputria
Copy link

yaroslavputria commented Sep 3, 2021

Hi All,

This line (if this._connectLock === true) prevents manually invoked reconnect, if the close method was called before the connection has ever been established.

My case: user decides when he wants to stop reconnecting retries, but later he should be able to proceed with reconnecting retries.

Could you please adjust the reconnect method (I hope it's not been used internally and it will not affect other workflows) to be able to call "force" reconnect manually?

Thanks,
Yaroslav

@nadine-nguyen
Copy link

nadine-nguyen commented May 3, 2022

I've also needed this use case too.
What I've done as a temporary solution is add these two lines after this line in the connect() method:

...
this._debug('max retries reached', this._retryCount, '>=', maxRetries);
+   this._shouldReconnect = false;
+   this._connectLock = false;
return
...

And also add this line in the close() method:

...
this._closeCalled = true;
+ this._connectLock = false;
this._shouldReconnect = false;
...

@ppena-LiveData
Copy link

ppena-LiveData commented May 12, 2022

The fix is just to also set this._connectLock = false; in the if (this._closeCalled) case of _connect(), i.e. after line 378 in reconnecting-websocket.ts, since the return on line 379 is preventing the this._connectLock = false on line 386 from running.

@votsa
Copy link

votsa commented Jun 3, 2022

There is another bug/issue. After this._retryCount reaches maxRetries, this._connectLock remains true and there is no way to set it to false so reconnect() method does not have any effect.

@ppena-LiveData
Copy link

Good catch! Yes, the early exit from _connect() in the if (this._retryCount >= maxRetries) block also needs to reset this._connectLock = false, just like the early exit in if (this._closeCalled).

alecgibson added a commit to reedsy/reconnecting-websocket that referenced this issue Nov 17, 2022
This change fixes two issues described here:
pladaria#165

 1. It's impossible to reconnect after `maxRetries` is exceeded, because
    the lock is never released
 2. It's impossible to reconnect if `close()` was called before the
    connection has been established

This change adds tests and fixes as discussed in the above issue.
alecgibson added a commit to reedsy/reconnecting-websocket that referenced this issue Nov 17, 2022
This change fixes two issues described here:
pladaria#165

 1. It's impossible to reconnect after `maxRetries` is exceeded, because
    the lock is never released
 2. It's impossible to reconnect if `close()` was called before the
    connection has been established

This change adds tests and fixes as discussed in the above issue.
alecgibson added a commit to reedsy/reconnecting-websocket that referenced this issue Nov 17, 2022
This change fixes two issues described here:
pladaria#165

 1. It's impossible to reconnect after `maxRetries` is exceeded, because
    the lock is never released
 2. It's impossible to reconnect if `close()` was called before the
    connection has been established

This change adds tests and fixes as discussed in the above issue.
@alecgibson
Copy link

I think @ppena-LiveData 's solution is the correct one.

If you reset _connectLock in the close() method, you can wind up opening several WebSockets if you rapidly call close() and reconnect() in quick succession.

This is a test case that passes if you keep the _connectLock reset in the _wait() promise resolution, but fails if you move it to close():

test('rapidly toggling connection', done => {
    const wss = new WebSocketServer({port: PORT});
    const ws = new ReconnectingWebSocket(URL, undefined, {
        minReconnectionDelay: 100,
        maxReconnectionDelay: 200,
    });

    ws.close();
    ws.reconnect();
    ws.close();
    ws.reconnect();

    let connections = 0;
    wss.on('connection', () => {
        connections++;
    });

    ws.addEventListener('open', () => {
        wss.close(() => {
            setTimeout(() => {
                expect(connections).toBe(1);
                done();
            }, 1000);
        });
    });
});

@alecgibson
Copy link

Also, since I've written them if anyone wants tests for the other cases discussed here:

test('reconnect after max retries', done => {
    const ws = new ReconnectingWebSocket(URL, undefined, {
        maxRetries: 1,
        maxReconnectionDelay: 200,
    });

    let closed = false;
    ws.addEventListener('error', () => {
        if (ws.retryCount === 1 && !closed) {
            const wss = new WebSocketServer({port: PORT});
            ws.reconnect();
            ws.addEventListener('open', () => {
                wss.close(() => {
                    closed = true;
                    setTimeout(() => {
                        done();
                    }, 1000);
                });
            });
        }
    });
});
test('reconnect after closing during connection', done => {
    const wss = new WebSocketServer({port: PORT});
    const ws = new ReconnectingWebSocket(URL, undefined, {
        minReconnectionDelay: 100,
        maxReconnectionDelay: 200,
    });

    ws.close();
    setTimeout(() => {
        ws.reconnect();

        ws.addEventListener('open', () => {
            wss.close(() => {
                setTimeout(() => {
                    done();
                }, 1000);
            });
        });
    }, 1000);
});

@nadine-nguyen
Copy link

@alecgibson Great catch! My mistake, use @ppena-LiveData's solutions 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants