Skip to content

Commit a5c394a

Browse files
committed
set default ringing timeout
1 parent 69f1784 commit a5c394a

3 files changed

Lines changed: 36 additions & 17 deletions

File tree

livekit-api/livekit/api/_dial_timeout.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,41 @@
1414
]
1515
"""@private"""
1616

17-
# Calls that dial a phone (SIP CreateSIPParticipant with wait_until_answered and
18-
# TransferSIPParticipant; WhatsApp AcceptWhatsAppCall with wait_until_answered)
19-
# take longer than a normal request.
20-
DIAL_TIMEOUT = 30.0
17+
# Ring window (seconds) assumed when a request doesn't set ringing_timeout;
18+
# matches the server default. A dialing request must outlast it.
19+
DEFAULT_RINGING_TIMEOUT = 30.0
2120
"""@private"""
2221

2322
# A dialing request must outlast the ringing window, or it would abort before
2423
# the call can be answered. Keep the request timeout at least this many seconds
25-
# above the request's ringing_timeout.
24+
# above the ringing timeout.
2625
RINGING_TIMEOUT_MARGIN = 2.0
2726
"""@private"""
2827

2928

29+
def pin_ringing_timeout(request: DialRequest) -> None:
30+
"""Set the ring window explicitly on a dialing request when the caller left it
31+
unset, so the derived request timeout doesn't depend on the server's default
32+
(which could change out from under us).
33+
34+
@private
35+
"""
36+
if not request.HasField("ringing_timeout"):
37+
request.ringing_timeout.seconds = int(DEFAULT_RINGING_TIMEOUT)
38+
39+
3040
def dial_timeout(user_timeout: Optional[float], request: DialRequest) -> float:
31-
"""Request timeout (seconds) for a phone-dialing call: the user-supplied
32-
value (or the dial default) raised, when needed, to stay at least
33-
RINGING_TIMEOUT_MARGIN above the request's ringing_timeout.
41+
"""Request timeout (seconds) for a phone-dialing call: the ring window plus a
42+
margin, so the request doesn't abort before the call can be answered. The
43+
ring window is the request's ringing_timeout when set, else
44+
DEFAULT_RINGING_TIMEOUT. A longer user_timeout is honored; a shorter one is
45+
raised to the floor.
3446
3547
@private
3648
"""
37-
effective = user_timeout if user_timeout else DIAL_TIMEOUT
3849
if request.HasField("ringing_timeout"):
39-
effective = max(effective, request.ringing_timeout.seconds + RINGING_TIMEOUT_MARGIN)
40-
return effective
50+
ring: float = request.ringing_timeout.seconds
51+
else:
52+
ring = DEFAULT_RINGING_TIMEOUT
53+
floor = ring + RINGING_TIMEOUT_MARGIN
54+
return max(user_timeout if user_timeout else floor, floor)

livekit-api/livekit/api/connector_service.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
ConnectTwilioCallResponse,
1919
)
2020
from ._service import Service
21-
from ._dial_timeout import dial_timeout
21+
from ._dial_timeout import dial_timeout, pin_ringing_timeout
2222
from .access_token import VideoGrants
2323

2424
SVC = "Connector"
@@ -129,7 +129,9 @@ async def accept_whatsapp_call(
129129
client_timeout: Optional[aiohttp.ClientTimeout] = None
130130
if request.wait_until_answered:
131131
# Waiting for the call to be answered dials a phone, which takes
132-
# longer than a normal request and must outlast ringing.
132+
# longer than a normal request and must outlast ringing. Pin the ring
133+
# window so the timeout doesn't depend on the server's default.
134+
pin_ringing_timeout(request)
133135
client_timeout = aiohttp.ClientTimeout(total=dial_timeout(timeout, request))
134136
elif timeout:
135137
client_timeout = aiohttp.ClientTimeout(total=timeout)

livekit-api/livekit/api/sip_service.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
SIPTransport,
3636
)
3737
from ._service import Service
38-
from ._dial_timeout import dial_timeout as _dial_timeout
38+
from ._dial_timeout import dial_timeout as _dial_timeout, pin_ringing_timeout as _pin_ringing_timeout
3939
from .access_token import VideoGrants, SIPGrants
4040

4141
SVC = "SIP"
@@ -784,7 +784,9 @@ async def create_sip_participant(
784784
client_timeout: Optional[aiohttp.ClientTimeout] = None
785785
if create.wait_until_answered:
786786
# Dialing a phone and waiting for an answer takes longer than a
787-
# normal call, and the request must outlast ringing.
787+
# normal call, and the request must outlast ringing. Pin the ring
788+
# window so the timeout doesn't depend on the server's default.
789+
_pin_ringing_timeout(create)
788790
client_timeout = aiohttp.ClientTimeout(total=_dial_timeout(timeout, create))
789791
elif timeout:
790792
# obey user specified timeout
@@ -823,8 +825,9 @@ async def transfer_sip_participant(
823825
Updated SIP participant information
824826
"""
825827
# Transferring a call dials a phone, which takes longer than a normal
826-
# call, so use a longer default unless the user specified a timeout, and
827-
# keep the request alive past ringing so the destination can answer.
828+
# call, so keep the request alive past ringing. Pin the ring window so the
829+
# timeout doesn't depend on the server's default.
830+
_pin_ringing_timeout(transfer)
828831
client_timeout = aiohttp.ClientTimeout(total=_dial_timeout(timeout, transfer))
829832
return await self._client.request(
830833
SVC,

0 commit comments

Comments
 (0)