Skip to content

Commit 7498d6f

Browse files
committed
also handle whatsapp dial timeout
1 parent 753157a commit 7498d6f

3 files changed

Lines changed: 49 additions & 26 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from __future__ import annotations
2+
3+
from typing import Optional
4+
5+
# Calls that dial a phone (SIP CreateSIPParticipant with wait_until_answered and
6+
# TransferSIPParticipant; WhatsApp AcceptWhatsAppCall with wait_until_answered)
7+
# take longer than a normal request.
8+
DIAL_TIMEOUT = 30.0
9+
"""@private"""
10+
11+
# A dialing request must outlast the ringing window, or it would abort before
12+
# the call can be answered. Keep the request timeout at least this many seconds
13+
# above the request's ringing_timeout.
14+
RINGING_TIMEOUT_MARGIN = 2.0
15+
"""@private"""
16+
17+
18+
def dial_timeout(user_timeout: Optional[float], request) -> float:
19+
"""Request timeout (seconds) for a phone-dialing call: the user-supplied
20+
value (or the dial default) raised, when needed, to stay at least
21+
RINGING_TIMEOUT_MARGIN above the request's ringing_timeout.
22+
23+
@private
24+
"""
25+
effective = user_timeout if user_timeout else DIAL_TIMEOUT
26+
if request.HasField("ringing_timeout"):
27+
effective = max(effective, request.ringing_timeout.seconds + RINGING_TIMEOUT_MARGIN)
28+
return effective

livekit-api/livekit/api/connector_service.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import aiohttp
4+
from typing import Optional
45

56
from livekit.protocol.connector_whatsapp import (
67
DialWhatsAppCallRequest,
@@ -17,6 +18,7 @@
1718
ConnectTwilioCallResponse,
1819
)
1920
from ._service import Service
21+
from ._dial_timeout import dial_timeout
2022
from .access_token import VideoGrants
2123

2224
SVC = "Connector"
@@ -106,23 +108,39 @@ async def connect_whatsapp_call(
106108
)
107109

108110
async def accept_whatsapp_call(
109-
self, request: AcceptWhatsAppCallRequest
111+
self,
112+
request: AcceptWhatsAppCallRequest,
113+
*,
114+
timeout: Optional[float] = None,
110115
) -> AcceptWhatsAppCallResponse:
111116
"""
112117
Accept an inbound WhatsApp call
113118
114119
Args:
115120
request: AcceptWhatsAppCallRequest containing call parameters and SDP
121+
timeout: Optional request timeout in seconds. When the request waits
122+
for an answer (wait_until_answered), it defaults to a longer value
123+
(dialing takes time) and is raised, if needed, to stay above the
124+
request's ringing_timeout.
116125
117126
Returns:
118127
AcceptWhatsAppCallResponse with the room name
119128
"""
129+
client_timeout: Optional[aiohttp.ClientTimeout] = None
130+
if request.wait_until_answered:
131+
# Waiting for the call to be answered dials a phone, which takes
132+
# longer than a normal request and must outlast ringing.
133+
client_timeout = aiohttp.ClientTimeout(total=dial_timeout(timeout, request))
134+
elif timeout:
135+
client_timeout = aiohttp.ClientTimeout(total=timeout)
136+
120137
return await self._client.request(
121138
SVC,
122139
"AcceptWhatsAppCall",
123140
request,
124141
self._auth_header(VideoGrants(room_create=True)),
125142
AcceptWhatsAppCallResponse,
143+
timeout=client_timeout,
126144
)
127145

128146
async def connect_twilio_call(

livekit-api/livekit/api/sip_service.py

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import aiohttp
44
import warnings
5-
from typing import Optional, Union
5+
from typing import Optional
66

77
from livekit.protocol.models import ListUpdate
88
from livekit.protocol.sip import (
@@ -35,35 +35,12 @@
3535
SIPTransport,
3636
)
3737
from ._service import Service
38+
from ._dial_timeout import dial_timeout as _dial_timeout
3839
from .access_token import VideoGrants, SIPGrants
3940

4041
SVC = "SIP"
4142
"""@private"""
4243

43-
# Calls that dial a phone (CreateSIPParticipant with wait_until_answered,
44-
# TransferSIPParticipant) take longer than a normal request.
45-
SIP_DIAL_TIMEOUT = 30.0
46-
"""@private"""
47-
48-
# A dialing request must outlast the ringing window, or it would abort before
49-
# the call can be answered. Keep the request timeout at least this many seconds
50-
# above the request's ringing_timeout.
51-
RINGING_TIMEOUT_MARGIN = 2.0
52-
"""@private"""
53-
54-
55-
def _dial_timeout(
56-
user_timeout: Optional[float],
57-
request: Union[CreateSIPParticipantRequest, TransferSIPParticipantRequest],
58-
) -> float:
59-
"""Request timeout (seconds) for a phone-dialing call: the user-supplied
60-
value (or the dial default) raised, when needed, to stay at least
61-
RINGING_TIMEOUT_MARGIN above the request's ringing_timeout."""
62-
effective = user_timeout if user_timeout else SIP_DIAL_TIMEOUT
63-
if request.HasField("ringing_timeout"):
64-
effective = max(effective, request.ringing_timeout.seconds + RINGING_TIMEOUT_MARGIN)
65-
return effective
66-
6744

6845
class SipService(Service):
6946
"""Client for LiveKit SIP Service API

0 commit comments

Comments
 (0)