Skip to content

Fix bug where max call duration was not being respected for outbound calls. - #762

Open
alexfish8 wants to merge 12 commits into
mainfrom
afish/max-call-duration
Open

Fix bug where max call duration was not being respected for outbound calls.#762
alexfish8 wants to merge 12 commits into
mainfrom
afish/max-call-duration

Conversation

@alexfish8

@alexfish8 alexfish8 commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Also in this PR:

  • A couple of nil checks in outbound.go
    • Add a nil check against *outboundCall.media in outboundCall.close (if the call to NewMediaPort in newCall fails, then we'd hit this nil deref).
    • Add a nil check against the response returned from selecting from tx.Responses in `sipResponse.
  • Make one of the outbound test utility channels buffered to avoid a race in the tests.

@alexfish8
alexfish8 requested a review from a team as a code owner July 28, 2026 18:33

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

@alexfish8
alexfish8 requested review from a team and removed request for a team July 28, 2026 18:43
Comment thread pkg/sip/outbound.go Outdated
Comment thread pkg/sip/outbound.go Outdated
Comment thread pkg/sip/outbound.go
c.CloseWith(ctx, EndCall{
Status: CallHangup,
Term: stats.Success("max-call-duration"),
Reason: livekit.DisconnectReason_CLIENT_INITIATED,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm.. Would DisconnectReason_CONNECTION_TIMEOUT be more accurate here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the inbound path times out due to max call duration being exceeded, the reason is given as CLIENT_INITIATED. Consistency aside, CLIENT_INITIATED feels more appropriate, as, ultimately, it was the client's request's configuration that caused the call to end early (but, I don't feel super strongly here. I can change both the inbound / outbound paths to give CONNECTION_TIMEOUT as the reason if you think that'd be more appropriate.)

@alexfish8 alexfish8 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the reviews!

Comment thread pkg/sip/outbound.go Outdated
Comment thread pkg/sip/outbound.go
c.CloseWith(ctx, EndCall{
Status: CallHangup,
Term: stats.Success("max-call-duration"),
Reason: livekit.DisconnectReason_CLIENT_INITIATED,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the inbound path times out due to max call duration being exceeded, the reason is given as CLIENT_INITIATED. Consistency aside, CLIENT_INITIATED feels more appropriate, as, ultimately, it was the client's request's configuration that caused the call to end early (but, I don't feel super strongly here. I can change both the inbound / outbound paths to give CONNECTION_TIMEOUT as the reason if you think that'd be more appropriate.)

Comment thread pkg/sip/outbound.go Outdated
devin-ai-integration[bot]

This comment was marked as resolved.

Comment thread pkg/sip/client.go
// Detach this context from the context of the RPC so that the RPC returning
// doesn't cause the call to end prematurely.
go func() {
detachedCtx, detatchedCancel := context.WithDeadline(context.WithoutCancel(ctx), deadline)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
detachedCtx, detatchedCancel := context.WithDeadline(context.WithoutCancel(ctx), deadline)
detachedCtx, detachedCancel := context.WithDeadline(context.WithoutCancel(ctx), deadline)

Comment thread pkg/sip/client.go
// doesn't cause the call to end prematurely.
go func() {
detachedCtx, detatchedCancel := context.WithDeadline(context.WithoutCancel(ctx), deadline)
defer detatchedCancel()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defer detatchedCancel()
defer detachedCancel()

Comment thread pkg/sip/outbound.go
case <-ctx.Done():
c.CloseWith(ctx, EndCall{
Status: CallHangup,
Term: stats.Success("hangup"),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of scope of this PR, but I think it's beneficial to differentiate max-duration reached vs normal hangup. Feel free to create a follow up ticket for this 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants