From 509fdf6c3722484af1e6c2e4ab38ab616937f632 Mon Sep 17 00:00:00 2001 From: Hoan Luu Huu <110280845+xquanluu@users.noreply.github.com> Date: Tue, 8 Sep 2026 00:42:20 +0700 Subject: [PATCH] Fix/siprec survives fs transfer (#249) * fix: keep siprec recording alive across a feature server transfer A cross-feature-server move (enqueue/dequeue or conference) re-negotiates the feature-server leg in _onFeatureServerTransfer, but nothing rebuilt the rtpengine subscription the SIPREC recording forks from, so the recorder went silent from the moment the call moved. The fresh destroy handler installed on the new leg also dropped the _stopRecording() call the original handlers have, so the SIPREC dialog was never BYEd and the recorder had to wait out its media timeout. Rebuild the subscription after the transfer re-negotiates media, and stop the recording when the transferred leg ends. The resubscribe call is guarded so this is safe to deploy before @jambonz/siprec-client-utils is bumped. Co-Authored-By: Claude Opus 5 (1M context) * fix: drop the siprec re-subscribe, keep the missing teardown Running the cross-feature-server move against a real two-feature-server cluster showed the rtpengine subscription survives the REFER on its own: with resubscribe() removed, the fork still carried the post-transfer conversation (50 packets/s on both streams, and the words spoken after the move transcribed straight out of the recording). rtpengine keeps non-offer-answer subscriptions across an answer, so there was never anything to rebuild - the earlier commit was fixing a fault that does not exist. What does fail, and what this branch still fixes, is the teardown: the destroy handler installed on the transferred leg never stopped the recording, so the recorder was left without a BYE. Co-Authored-By: Claude Opus 5 (1M context) --------- Co-authored-by: Claude Opus 5 (1M context) --- lib/call-session.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/call-session.js b/lib/call-session.js index 07bc8a3..6e0397f 100644 --- a/lib/call-session.js +++ b/lib/call-session.js @@ -1109,6 +1109,7 @@ Duration=${payload.duration} ` this.rtpEngineResource.destroy(); this.activeCallIds.delete(this.req.get('Call-ID')); uac.other.destroy(); + this._stopRecording(); this.srf.endSession(this.req); });