fix(data-channel): connect failure with multiple meetings#4941
fix(data-channel): connect failure with multiple meetings#4941Tianhui-Han wants to merge 8 commits intowebex:nextfrom
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a1d4e9958a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| typeof requestUrl === 'string' && requestUrl.includes(PRACTICE_SESSION_URL_MARKER) | ||
| ? LLM_PRACTICE_SESSION | ||
| : LLM_DEFAULT_SESSION; |
There was a problem hiding this comment.
Detect practice session from encoded URL correctly
requestUrl.includes('practiceSession') misclassifies practice-session datachannel requests when the locus path is encoded (the normal URL shape is /datachannel/.../locus/<base64>/registrations, e.g. packages/@webex/plugin-meetings/test/unit/spec/fixture/locus.js), because the plaintext marker does not appear inside base64. In that case the interceptor always picks LLM_DEFAULT_SESSION, resolves the wrong meeting/token, and retries 401/403 with an invalid token for practice-session traffic.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6c2f4e5e15
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (!result?.body) return undefined; | ||
| const {datachannelToken, dataChannelTokenType} = result.body; |
There was a problem hiding this comment.
Throw when token refresh returns no payload
When meeting.refreshDataChannelToken() (or internal.llm.refreshDataChannelToken()) fails, it can return null; this new guard converts that into undefined and the callers still overwrite Data-Channel-Auth-Token with that value. In the expired-token flow this strips the auth header, sends an unauthenticated request, and then onResponseError skips refresh entirely because !token is true, so recovery stops after a transient refresh failure. Previously this path threw during destructuring and preserved the existing header instead of clearing it.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b559499f74
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| // If we couldn't identify the session from the URL, default to LLM_DEFAULT_SESSION | ||
| if (!sessionId) { | ||
| sessionId = LLM_DEFAULT_SESSION; | ||
| } |
There was a problem hiding this comment.
Avoid default-session fallback on unmatched request URLs
When URL matching fails, this code unconditionally routes refresh to LLM_DEFAULT_SESSION, which can refresh the wrong meeting/token for practice-session traffic. This is reachable because request URLs are mutated earlier by host mapping (packages/@webex/webex-core/src/lib/interceptors/hostmap.js, onRequest rewrites options.uri), while getDatachannelUrl() stores the original session URL; after rewrite, startsWith() can miss and sessionId falls back to default. In multi-session webinars, that misroute returns a default-session token for a practice-session request and causes repeated 401/403 retries instead of recovery.
Useful? React with 👍 / 👎.
| export const LOCUS_URL = 'locusUrl'; | ||
| export const END = 'end'; | ||
| export const LLM_PRACTICE_SESSION = 'llm-practice-session'; | ||
| export const LLM_DEFAULT_SESSION = 'llm-default-session'; |
There was a problem hiding this comment.
we already have LLM_DEFAULT_SESSION defined here: https://github.com/webex/webex-js-sdk/blob/next/packages/%40webex/internal-plugin-llm/src/constants.ts#L4
it would be better to use that instead of creating a copy
| result = await meeting.refreshDataChannelToken(); | ||
| } else { | ||
| // @ts-ignore | ||
| result = await this.internal.llm.refreshDataChannelToken(); |
There was a problem hiding this comment.
looking at this code makes me realize that existing LLM module APIs are a bit flawed.... LLM plugin's refreshDataChannelToken() and setDatachannelToken() methods should take session ids as arguments, shouldn't they?
|
|
||
| if (typeof requestUrl === 'string') { | ||
| // @ts-ignore | ||
| const psDatachannelUrl = this.internal.llm.getDatachannelUrl?.(LLM_PRACTICE_SESSION); |
There was a problem hiding this comment.
this code will stop working when any meeting object creates an LLM session with a non-default session id or if we ever have more than 1 active LLM connection. Wouldn't it be better to get the list of all LLM sessions and among them look for the locus url? or maybe even don't bother with checking the llm sessions and just look up the meeting by locus url and call meeting.refreshDataChannelToken() on it?
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9a34e42cc3
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (psDatachannelUrl && requestUrl.startsWith(psDatachannelUrl)) { | ||
| sessionId = LLM_PRACTICE_SESSION; | ||
| } else if (defaultDatachannelUrl && requestUrl.startsWith(defaultDatachannelUrl)) { | ||
| sessionId = LLM_DEFAULT_SESSION; |
There was a problem hiding this comment.
Match session URLs resiliently to hostmap rewrites
requestUrl.startsWith(ps/defaultDatachannelUrl) compares full absolute URLs, but HostMapInterceptor.onRequest() rewrites options.uri to a mapped host while internal.llm.getDatachannelUrl() stores the original registration URL from registerAndConnect(). In that common path the comparison fails, sessionId is left unset, and the new default-session fallback routes practice-session retries to the default meeting token, causing repeated 401/403 instead of recovery. This needs a host-agnostic match (or direct fallback to the singleton refresh handler when URL matching is inconclusive).
Useful? React with 👍 / 👎.
… via URL matching
… safe fallback routing
This pull request addresses
https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-809708
by making the following changes
When multiple meetings coexist, the shared refresh handler gets overwritten and PS token refresh targets the wrong meeting (401/403).
Fix: interceptor now resolves the owning meeting from the request URL at refresh time, falling back to the singleton handler if unresolved.
Change Type
The following scenarios were tested
< ENUMERATE TESTS PERFORMED, WHETHER MANUAL OR AUTOMATED >
The GAI Coding Policy And Copyright Annotation Best Practices
I certified that
Make sure to have followed the contributing guidelines before submitting.