-
Notifications
You must be signed in to change notification settings - Fork 386
fix(calling): update call keepalive retry logic #4557
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
Conversation
Kesari3008
left a comment
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.
Haven't looked at the test files for now, because there are comments for code changes.
adhmenon
left a comment
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.
Is it possible to test this with the agent desktop?
Just want to ensure it does not break the flow.
adhmenon
left a comment
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.
Approved.
But let us test once with agent desktop just to be safe.
| expect(emitSpy).toHaveBeenCalledWith(CALL_EVENT_KEYS.DISCONNECT, call.getCorrelationId()); | ||
| }); | ||
|
|
||
| it('session refresh 403 ends the call without emitting error', async () => { |
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.
403 case is update here.
| setTimeout(() => { | ||
| /* We first post the status and then recursively call the handler which | ||
| * starts the timer again | ||
| */ | ||
| this.postStatus(); | ||
| this.sendCallStateMachineEvt({type: 'E_CALL_ESTABLISHED'}); | ||
| }, interval * 1000); |
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.
This setTimeout is not required as it was causing the this.postStatus() call to be made twice - once here and next on invoking the handleCallEstablished through state machine.
Now we are only calling handleCallEstablished through state machine immediately as the handleCallEstablished makes the keepalive call inside the setInterval which adds the required delay and keeps the counter consistent.
Kesari3008
left a comment
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.
Approving the PR but there are still significant changes needed. Please address these
| this.emit(CALL_EVENT_KEYS.DISCONNECT, this.getCorrelationId()); | ||
| this.callKeepaliveRetryCount = 0; | ||
|
|
||
| return; |
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.
We shouldn't skip logs uploading for final error cases, this return would cause that
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.
Done
| this.postStatus(); | ||
| this.sendCallStateMachineEvt({type: 'E_CALL_ESTABLISHED'}); | ||
| }, interval * 1000); | ||
| this.callKeepaliveRetryCount += 1; |
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.
We didn't need to remove the setTimeout. Retry logic was implemented in a way that if it fails, we were immediately trying one more time and schedule the timeout to try it again after specific interval. Even if we wanted to avoid the postStatus being sent twice, we should just remove postStatus and keep setting the state machine to established with a interval timeout to trigger the keepalive retry
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.
Even if we wanted to avoid the postStatus being sent twice, we should just remove postStatus and keep setting the state machine to established with a interval timeout to trigger the keepalive retry
This logic is already there. I have removed the unnecessary setTimeout and postStatus, instead I am directly invoking the logic with the state machine. Please check the new logic. If required we can discuss over a call
| this.postStatus(); | ||
| this.sendCallStateMachineEvt({type: 'E_CALL_ESTABLISHED'}); | ||
| }, interval * 1000); | ||
| this.callKeepaliveRetryCount += 1; |
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.
With this logic with the first keepalive retry itself, count will start increasing
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.
This is only being increased in case of error.
| endSpy | ||
| ); | ||
|
|
||
| expect(emitted).toBe(true); |
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.
Add check for for abort being false for non-final error cases
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.
Done
| expect(retrySpy).not.toHaveBeenCalled(); | ||
| }); | ||
|
|
||
| it('503 during keepalive with retry-after does not emit and retries with interval', async () => { |
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.
it should say does not emit what
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.
Changed to -> 503 during keepalive with retry-after does not invoke emitterCb and retries with interval
| logObj.file | ||
| ); | ||
|
|
||
| expect(emitted).toBe(true); |
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.
we should be check for accurate emitter callback where we emit error event instead of plain setting it true or false. Or just pass jest.fn() and check for it's invocation
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.
This check ensures that the passed emitterCb is being invoked. We don't need to make it complicated.
|
|
||
| expect(clearInterval).toHaveBeenCalledTimes(1); | ||
| expect(funcSpy).toBeCalledTimes(1); | ||
| expect(emitSpy).toHaveBeenCalledWith(CALL_EVENT_KEYS.DISCONNECT, call.getCorrelationId()); |
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.
we should add expect to check for end API being invoked, media connection getting closed and call getting cleared from callCollection
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.
Wouldn't that make it an integration test? There would be a separate unit test for that already present
| call['handleCallEstablished']({} as CallEvent); | ||
| } | ||
|
|
||
| jest.advanceTimersByTime(DEFAULT_SESSION_TIMER); |
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.
we should only advance here as per retyr after and not default session timer right
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.
First time invocation of postStatus will only happen after the DEFAULT_SESSION_TIMER
| jest.spyOn(call, 'postStatus').mockRejectedValue(errorPayload); | ||
|
|
||
| // Manually set the retry count to 3 so it becomes 4 after increment | ||
| call['callKeepaliveRetryCount'] = 3; |
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.
We should let the code run 4 times and count getting increased on its own. And add expect for postStatus being invoked 4 times too
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.
Done
e2e01ce to
e044e2d
Compare
COMPLETES #< CAI-7258 >
This pull request addresses
Adds the call keepalive error handling scenarios for 4xx and 5xx cases where for 4xx cases call cleanup happens and for 5xx keepalive retries are done based on the value received in the response header
retry-afterfollowed by fallback value if it's not present.by making the following changes
Normal keepalive for call will be 10 minutes but if receives 5xx response then it will schedule the re-tries based on the after-retry header value and fallback to 30 seconds
Vidcast - https://app.vidcast.io/share/670a12d0-1b16-4561-8d86-f34df10e3a63
Change Type
The following scenarios were tested
< ENUMERATE TESTS PERFORMED, WHETHER MANUAL OR AUTOMATED >
Tested the following with the burp suite (to update the response header)
The GAI Coding Policy And Copyright Annotation Best Practices
I certified that
Make sure to have followed the contributing guidelines before submitting.