-
-
Notifications
You must be signed in to change notification settings - Fork 594
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
Only re-prepare MatrixrRTC delayed disconnection event on 404 #4575
base: develop
Are you sure you want to change the base?
Only re-prepare MatrixrRTC delayed disconnection event on 404 #4575
Conversation
With it being set to one the following issue could occur: ``` // If sending state cancels your own delayed state, prepare another delayed state // TODO: Remove this once MSC4140 is stable & doesn't cancel own delayed state if (this.disconnectDelayId !== undefined) { try { const knownDisconnectDelayId = this.disconnectDelayId; await resendIfRateLimited( () => this.client._unstable_updateDelayedEvent( knownDisconnectDelayId, UpdateDelayedEventAction.Restart, ), 1000, ); } catch (e) { logger.warn("Failed to update delayed disconnection event, prepare it again:", e); this.disconnectDelayId = undefined; await prepareDelayedDisconnection(); } } ``` This code looks like the `catch(e)` could never be triggered with 429 (rate limit) because they would be caught by `await resendIfRateLimited`. EXCEPT that this is only happening once: `resendIfRateLimited<T>(func: () => Promise<T>, numRetriesAllowed: number = 1)`. So as soon as the server sends two rate limits in a row we get the following: - we get into the `catch(e)` because of the rate limit - we forget about `this.disconnectDelayId = undefined` - we start a new delayed event `await prepareDelayedDisconnection();` - we do not anymore update the old delayed event which is still running! - the running delay event will make us disconnect from the call (call member becomes `{}`) - we get into our outher error catching mechanism that resends the new state event - this cancels the newly created delay leave event (`await prepareDelayedDisconnection();`) - and create another delay leave event. - but if we are still reate limited (chances are really high due to the reconnect), this loop will REPEAT
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to see a test case for this, please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other questions:
- It doesn't make sense that we would retry 1000 times. Surely we want to stop when the call disconnects?
- What prevents the being more than one
prepareDelayedDisconnection()
running at a time?
ba4c95d
to
81cd4f8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having discussed this with @toger5 it is not going to be feasible to add a new test case at this time.
Instead, we will on refactoring the class to make it more testable and also address the questions about having multiple timers running at once.
n.b. The original scope of this PR has changed (reduced). It is not feasible to test this at the moment. We are planning a refactor of this class to make it easier to test.
With it being set to one the following issue could occur:
This code looks like the
catch(e)
could never be triggered with 429 (rate limit) because they would be caught byawait resendIfRateLimited
. EXCEPT that this is only happening once:resendIfRateLimited<T>(func: () => Promise<T>, numRetriesAllowed: number = 1)
. So as soon as the server sends two rate limits in a row we get the following:catch(e)
because of the rate limitthis.disconnectDelayId = undefined
await prepareDelayedDisconnection();
{}
)await prepareDelayedDisconnection();
)Checklist
public
/exported
symbols have accurate TSDoc documentation.