feat: add overall timeout parameter to remote client (#2550)

## Summary
- Adds an overall `timeout` parameter to `TimeoutConfig` that limits the
total time for the entire request
- Can be set via config or `LANCE_CLIENT_TIMEOUT` environment variable
- Exposed in Python and Node.js bindings
- Includes comprehensive tests

## Test plan
- [x] Unit tests for Rust TimeoutConfig
- [x] Integration tests for Python bindings  
- [x] Integration tests for Node.js bindings
- [x] All existing tests pass

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Will Jones
2025-08-04 10:06:55 -07:00
committed by GitHub
parent f23327af79
commit 02595dc475
6 changed files with 130 additions and 12 deletions

View File

@@ -17,6 +17,12 @@ class TimeoutConfig:
Attributes
----------
timeout: Optional[timedelta]
The overall timeout for the entire request. This includes connection,
send, and read time. If the entire request doesn't complete within
this time, it will fail. Default is None (no overall timeout).
This can also be set via the environment variable
`LANCE_CLIENT_TIMEOUT`, as an integer number of seconds.
connect_timeout: Optional[timedelta]
The timeout for establishing a connection. Default is 120 seconds (2 minutes).
This can also be set via the environment variable
@@ -31,6 +37,7 @@ class TimeoutConfig:
`LANCE_CLIENT_CONNECTION_TIMEOUT`, as an integer number of seconds.
"""
timeout: Optional[timedelta] = None
connect_timeout: Optional[timedelta] = None
read_timeout: Optional[timedelta] = None
pool_idle_timeout: Optional[timedelta] = None
@@ -50,6 +57,7 @@ class TimeoutConfig:
)
def __post_init__(self):
self.timeout = self.__to_timedelta(self.timeout)
self.connect_timeout = self.__to_timedelta(self.connect_timeout)
self.read_timeout = self.__to_timedelta(self.read_timeout)
self.pool_idle_timeout = self.__to_timedelta(self.pool_idle_timeout)

View File

@@ -798,6 +798,21 @@ def test_create_client():
assert isinstance(db.client_config, ClientConfig)
assert db.client_config.timeout_config.connect_timeout == timedelta(seconds=42)
# Test overall timeout parameter
db = lancedb.connect(
**mandatory_args,
client_config=ClientConfig(timeout_config={"timeout": 60}),
)
assert isinstance(db.client_config, ClientConfig)
assert db.client_config.timeout_config.timeout == timedelta(seconds=60)
db = lancedb.connect(
**mandatory_args,
client_config={"timeout_config": {"timeout": timedelta(seconds=60)}},
)
assert isinstance(db.client_config, ClientConfig)
assert db.client_config.timeout_config.timeout == timedelta(seconds=60)
db = lancedb.connect(
**mandatory_args, client_config=ClientConfig(retry_config={"retries": 42})
)