From 7745aaa76b77bd619a3127a331eea13ca41d0334 Mon Sep 17 00:00:00 2001 From: shishirng Date: Thu, 11 Jun 2026 13:02:25 -0400 Subject: [PATCH] [WIP] rtc: add RestartSessionTimer to re-anchor participant session duration (#4566) * rtc: add RestartSessionTimer to re-anchor participant session duration Exposes ParticipantImpl.RestartSessionTimer so the session timer can be re-anchored to the actual join time. Duration is only ever emitted once the participant becomes active, so re-anchoring at join keeps pre-join wall-clock out of the reported/billed duration. Adds the method to the LocalParticipant interface (fake regenerated) and a local protocol replace to pick up SessionTimer.Reset. Co-Authored-By: Claude Opus 4.8 (1M context) * tidy * update protocol * report ended at for inactive sessions --------- Co-authored-by: Claude Opus 4.8 (1M context) Co-authored-by: Paul Wells --- go.mod | 2 +- go.sum | 4 ++-- pkg/rtc/participant.go | 18 +++++++++++------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 889a72501..0c0976f4f 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/jxskiss/base62 v1.1.0 github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731 github.com/livekit/mediatransportutil v0.0.0-20260608063931-a3417d38cda0 - github.com/livekit/protocol v1.46.7-0.20260610055838-1459c54aadf6 + github.com/livekit/protocol v1.46.7-0.20260611165352-04a0fe5b5051 github.com/livekit/psrpc v0.7.2 github.com/mackerelio/go-osstat v0.2.7 github.com/magefile/mage v1.17.2 diff --git a/go.sum b/go.sum index e16452377..50302265b 100644 --- a/go.sum +++ b/go.sum @@ -160,8 +160,8 @@ github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731 h1:9x+U2HGLrSw5AT github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731/go.mod h1:Rs3MhFwutWhGwmY1VQsygw28z5bWcnEYmS1OG9OxjOQ= github.com/livekit/mediatransportutil v0.0.0-20260608063931-a3417d38cda0 h1:XHNNzebIKZRkLimla/hFGrAIX5EMWHctrgt3hLw7s+I= github.com/livekit/mediatransportutil v0.0.0-20260608063931-a3417d38cda0/go.mod h1:o8CFmAdrVwzJNOCsQCLUzXRjokkufNshnQHOe4fRaqU= -github.com/livekit/protocol v1.46.7-0.20260610055838-1459c54aadf6 h1:AK8JNLn2H3+ixSfh9gdFDqI+IpBV1YASGAusqaV5gFs= -github.com/livekit/protocol v1.46.7-0.20260610055838-1459c54aadf6/go.mod h1:jO+y05AU9Ec4JswDyuzKCZ4bhziOS0CzMqgnbj60Dzs= +github.com/livekit/protocol v1.46.7-0.20260611165352-04a0fe5b5051 h1:IYqiW7z5pblZBn6o0OHNz8MHd3wJ/TLJG4gh6lCI0/s= +github.com/livekit/protocol v1.46.7-0.20260611165352-04a0fe5b5051/go.mod h1:jO+y05AU9Ec4JswDyuzKCZ4bhziOS0CzMqgnbj60Dzs= github.com/livekit/psrpc v0.7.2 h1:6oZ+NODJ2pLyaT6VqDq1F4Qc/3TpDUSpyphj/P9MhQc= github.com/livekit/psrpc v0.7.2/go.mod h1:rAI+m2+/cb4x9RXhLRtUx5ZwdfjjXOl4zi46IjEetaw= github.com/mackerelio/go-osstat v0.2.7 h1:TCavZi10wF49bT6iQZ9eT2keGZQpC69MTDfdJej5e94= diff --git a/pkg/rtc/participant.go b/pkg/rtc/participant.go index bf2ebdb5b..f5f459e4e 100644 --- a/pkg/rtc/participant.go +++ b/pkg/rtc/participant.go @@ -405,19 +405,23 @@ func NewParticipant(params ParticipantParams) (*ParticipantImpl, error) { p.supervisor.OnPublicationError(p.onPublicationError) } + var timerStarted bool params.Reporter.RegisterFunc(func(ts time.Time, tx roomobs.ParticipantSessionTx) bool { - // Don't publish duration if participant never became active. Otherwise short-lived - // JOINING/JOINED -> DISCONNECTED transitions would still get rounded up to a - // minute by the session timer and inflate billed/reported duration. - if p.lastActiveAt.Load() == nil { - return !p.IsClosed() - } - if dts := p.disconnectedAt.Load(); dts != nil { ts = *dts tx.ReportEndTime(ts) } + // Don't publish duration if participant never became active. Otherwise short-lived + // JOINING/JOINED -> DISCONNECTED transitions would still get rounded up to a + // minute by the session timer and inflate billed/reported duration. + if lastActive := p.lastActiveAt.Load(); lastActive == nil { + return !p.IsClosed() + } else if !timerStarted { + timerStarted = true + p.params.SessionTimer.Reset(*lastActive) + } + tx.ReportKindCode(roomobs.ParticipantKindCode(p.Kind())) tx.ReportKindDetailsCodes(roomobs.ParticipantKindDetailsCodes(p.KindDetails()))