Skip to content

Commit 9a7d70b

Browse files
authored
Merge pull request #33 from koyeb/add-poll-interval
Expose poll_interval parameter and reduce the default polling interval
2 parents 9fbae0b + fdf2a9a commit 9a7d70b

5 files changed

Lines changed: 93 additions & 47 deletions

File tree

docs/sandbox.md

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,7 +1004,8 @@ def create(cls,
10041004
delete_after_delay: int = 0,
10051005
delete_after_inactivity_delay: int = 0,
10061006
app_id: Optional[str] = None,
1007-
enable_mesh: bool = None) -> Sandbox
1007+
enable_mesh: bool = None,
1008+
poll_interval: float = DEFAULT_POLL_INTERVAL) -> Sandbox
10081009
```
10091010

10101011
Create a new sandbox instance.
@@ -1039,6 +1040,7 @@ Create a new sandbox instance.
10391040
after this many seconds.
10401041
- `app_id` - If provided, create the sandbox service in an existing app instead of creating a new one.
10411042
- `enable_mesh` - Enable or disable mesh for this sandbox. Disabled by default
1043+
- `poll_interval` - Time between health checks in seconds when wait_ready is True (default: 0.5)
10421044

10431045

10441046
**Returns**:
@@ -1096,15 +1098,17 @@ Get a sandbox by service ID.
10961098

10971099
```python
10981100
def wait_ready(timeout: int = DEFAULT_INSTANCE_WAIT_TIMEOUT,
1099-
poll_interval: float = DEFAULT_POLL_INTERVAL) -> bool
1101+
poll_interval: Optional[float] = None) -> bool
11001102
```
11011103

1102-
Wait for sandbox to become ready with proper polling.
1104+
Wait for sandbox to become ready with exponential backoff polling.
1105+
1106+
Starts polling at 0.1s intervals, doubling each time up to poll_interval.
11031107

11041108
**Arguments**:
11051109

11061110
- `timeout` - Maximum time to wait in seconds
1107-
- `poll_interval` - Time between health checks in seconds
1111+
- `poll_interval` - Maximum time between health checks in seconds (defaults to instance poll_interval)
11081112

11091113

11101114
**Returns**:
@@ -1117,19 +1121,18 @@ Wait for sandbox to become ready with proper polling.
11171121

11181122
```python
11191123
def wait_tcp_proxy_ready(timeout: int = DEFAULT_INSTANCE_WAIT_TIMEOUT,
1120-
poll_interval: float = DEFAULT_POLL_INTERVAL) -> bool
1124+
poll_interval: Optional[float] = None) -> bool
11211125
```
11221126

11231127
Wait for TCP proxy to become ready and available.
11241128

1125-
Polls the deployment metadata until the TCP proxy information is available.
1126-
This is useful when enable_tcp_proxy=True was set during sandbox creation,
1127-
as the proxy information may not be immediately available.
1129+
Polls the deployment metadata with exponential backoff until the TCP proxy
1130+
information is available. Starts at 0.1s intervals, doubling up to poll_interval.
11281131

11291132
**Arguments**:
11301133

11311134
- `timeout` - Maximum time to wait in seconds
1132-
- `poll_interval` - Time between checks in seconds
1135+
- `poll_interval` - Maximum time between checks in seconds (defaults to instance poll_interval)
11331136

11341137

11351138
**Returns**:
@@ -1166,12 +1169,13 @@ def get_domain() -> Optional[str]
11661169

11671170
Get the public domain of the sandbox.
11681171

1169-
Returns the domain name (e.g., "app-name-org.koyeb.app") without protocol or path.
1170-
To construct the URL, use: f"https://{sandbox.get_domain()}"
1172+
Returns the domain (e.g., "app-name-org.koyeb.app/r/routing_key/" or
1173+
"app-name-org.koyeb.app") without protocol. To get the full URL with protocol,
1174+
use sandbox._get_url()
11711175

11721176
**Returns**:
11731177

1174-
- `Optional[str]` - The domain name or None if unavailable
1178+
- `Optional[str]` - The domain or None if unavailable
11751179

11761180
<a id="koyeb/sandbox.sandbox.Sandbox.get_tcp_proxy_info"></a>
11771181

@@ -1536,7 +1540,8 @@ async def create(cls,
15361540
delete_after_delay: int = 0,
15371541
delete_after_inactivity_delay: int = 0,
15381542
app_id: Optional[str] = None,
1539-
enable_mesh: bool = False) -> AsyncSandbox
1543+
enable_mesh: bool = False,
1544+
poll_interval: float = DEFAULT_POLL_INTERVAL) -> AsyncSandbox
15401545
```
15411546

15421547
Create a new sandbox instance with async support.
@@ -1573,6 +1578,7 @@ Create a new sandbox instance with async support.
15731578
after this many seconds.
15741579
- `app_id` - If provided, create the sandbox service in an existing app instead of creating a new one.
15751580
- `enable_mesh` - Enable or disable mesh for this sandbox. Disabled by default
1581+
- `poll_interval` - Time between health checks in seconds when wait_ready is True (default: 0.5)
15761582

15771583

15781584
**Returns**:
@@ -1591,15 +1597,17 @@ Create a new sandbox instance with async support.
15911597

15921598
```python
15931599
async def wait_ready(timeout: int = DEFAULT_INSTANCE_WAIT_TIMEOUT,
1594-
poll_interval: float = DEFAULT_POLL_INTERVAL) -> bool
1600+
poll_interval: Optional[float] = None) -> bool
15951601
```
15961602

1597-
Wait for sandbox to become ready with proper async polling.
1603+
Wait for sandbox to become ready with exponential backoff async polling.
1604+
1605+
Starts polling at 0.1s intervals, doubling each time up to poll_interval.
15981606

15991607
**Arguments**:
16001608

16011609
- `timeout` - Maximum time to wait in seconds
1602-
- `poll_interval` - Time between health checks in seconds
1610+
- `poll_interval` - Maximum time between health checks in seconds (defaults to instance poll_interval)
16031611

16041612

16051613
**Returns**:
@@ -1611,21 +1619,19 @@ Wait for sandbox to become ready with proper async polling.
16111619
#### wait\_tcp\_proxy\_ready
16121620

16131621
```python
1614-
async def wait_tcp_proxy_ready(
1615-
timeout: int = DEFAULT_INSTANCE_WAIT_TIMEOUT,
1616-
poll_interval: float = DEFAULT_POLL_INTERVAL) -> bool
1622+
async def wait_tcp_proxy_ready(timeout: int = DEFAULT_INSTANCE_WAIT_TIMEOUT,
1623+
poll_interval: Optional[float] = None) -> bool
16171624
```
16181625

16191626
Wait for TCP proxy to become ready and available asynchronously.
16201627

1621-
Polls the deployment metadata until the TCP proxy information is available.
1622-
This is useful when enable_tcp_proxy=True was set during sandbox creation,
1623-
as the proxy information may not be immediately available.
1628+
Polls the deployment metadata with exponential backoff until the TCP proxy
1629+
information is available. Starts at 0.1s intervals, doubling up to poll_interval.
16241630

16251631
**Arguments**:
16261632

16271633
- `timeout` - Maximum time to wait in seconds
1628-
- `poll_interval` - Time between checks in seconds
1634+
- `poll_interval` - Maximum time between checks in seconds (defaults to instance poll_interval)
16291635

16301636

16311637
**Returns**:
@@ -2235,6 +2241,9 @@ def health() -> Dict[str, str]
22352241

22362242
Check the health status of the server.
22372243

2244+
Uses a short timeout and no retries since callers (wait_ready)
2245+
already handle polling with backoff.
2246+
22382247
**Returns**:
22392248

22402249
Dict with status information
@@ -2243,6 +2252,7 @@ Check the health status of the server.
22432252
**Raises**:
22442253

22452254
- `requests.HTTPError` - If the health check fails
2255+
- `requests.Timeout` - If the health check times out
22462256

22472257
<a id="koyeb/sandbox.executor_client.SandboxClient.run"></a>
22482258

examples/02_create_sandbox_with_timing.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ def main(run_long_tests=False):
8888
name=f"example-sandbox-timed-{suffix}",
8989
wait_ready=True,
9090
api_token=api_token,
91+
# poll_interval=0.1,
9192
)
9293
create_duration = time.time() - create_start
9394
tracker.record("Sandbox creation", create_duration, "setup")

koyeb/sandbox/executor_client.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,15 +158,20 @@ def health(self) -> Dict[str, str]:
158158
"""
159159
Check the health status of the server.
160160
161+
Uses a short timeout and no retries since callers (wait_ready)
162+
already handle polling with backoff.
163+
161164
Returns:
162165
Dict with status information
163166
164167
Raises:
165168
requests.HTTPError: If the health check fails
169+
requests.Timeout: If the health check times out
166170
"""
167-
response = self._request_with_retry(
168-
"GET", f"{self.base_url}/health", timeout=self.timeout
171+
response = self._session.get(
172+
f"{self.base_url}/health", timeout=5
169173
)
174+
response.raise_for_status()
170175
return response.json()
171176

172177
def run(

0 commit comments

Comments
 (0)