fix(voice): capture activity to local before awaits in closeImplInner#1872
fix(voice): capture activity to local before awaits in closeImplInner#1872tsushanth wants to merge 1 commit into
Conversation
When close() races an activity transition that sets this.activity to undefined between the if-guard and subsequent awaits, accesses like this.activity.currentSpeech throw TypeError. Capturing the reference to a local variable at the top of the block makes all reads within the if-branch consistent regardless of concurrent mutations. Fixes livekit#1871
|
|
|
There was a problem hiding this comment.
🔴 Captured activity local variable not used for close(), defeating the purpose of the race-condition fix
The PR captures this.activity into a local activity variable at line 1529 to protect against concurrent mutation during the multiple await points in closeImplInner. However, line 1564 still uses this.activity?.close() instead of activity?.close(). A concurrent _updateActivity call can set this.activity = undefined at agent_session.ts:1176 when it sees this.closing = true (set at line 1524). If that happens between lines 1529 and 1564, the original activity captured in the local variable will never have close() called on it — resulting in a resource leak — while this.activity?.close() becomes a no-op.
(Refers to line 1564)
Was this helpful? React with 👍 or 👎 to provide feedback.
Fixes #1871
closeImplInnerreadsthis.activityacross multipleawaitboundaries without first capturing a local reference. Whenclose()races an activity transition that setsthis.activity = undefinedbetween the initialif (this.activity)guard and the subsequent awaited calls, accesses likethis.activity.currentSpeech?.waitForPlayout()throw aTypeError:Because the throw happens before
this.emit(Close, ...), theCloseevent is never emitted — so any application code that depends on the session close event silently never runs for those sessions.The fix captures
this.activityinto a localconst activityat the top of the block. All reads within theif (activity)branch then operate on the captured reference, which remains stable regardless of concurrent mutations tothis.activity.