Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ All fields live on `CreditLeaseConfig`. Durations are seconds. Everything below
| Option | Type | Default | Description |
|---|---|---|---|
| `mode` | `str` | `"auto"` | `client`, `server`, or `auto` (client when DataStream is running). |
| `default_reservation_ttl` | `float` | 60 | How long an unsettled hold survives. Capped at one hour in server mode. |
| `default_reservation_ttl` | `float` | 60 | How long an unsettled hold survives. Capped at 24 hours in server mode. |
| `default_lease_duration` | `float` | 300 | Lease lifetime requested at acquire and extend. |
| `default_lease_size` | `float` | 10000 | Credits requested per acquire, and the minimum extend tranche. |
| `low_water_mark` | `float` | 0.25 | Extend in the background when the lease balance dips below this fraction. |
Expand Down
8 changes: 4 additions & 4 deletions src/schematic/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@

# The longest hold the server will take. A longer configured TTL is clamped to
# it, rather than sent and rejected on every check.
MAX_RESERVATION_TTL = 3600.0
MAX_RESERVATION_TTL = 86400.0
# Room for the two clocks to disagree. expires_at is computed here and measured
# against the server's own clock, so a TTL sitting exactly on the cap is
# rejected whenever this process runs even slightly ahead.
Expand Down Expand Up @@ -159,7 +159,7 @@ class CreditLeaseConfig:
mode: CreditLeaseMode = "auto"
# How long a hold survives unsettled. Size it above the longest expected
# gap between check() and track_with_reservation(). Anything above the
# server's one hour cap is clamped, in server mode. Client mode keeps it:
# server's 24 hour cap is clamped, in server mode. Client mode keeps it:
# the TTL only drives the local sweeper there.
default_reservation_ttl: float = DEFAULT_RESERVATION_TTL
# Lease lifetime requested at acquire and extend. Default 5 minutes.
Expand Down Expand Up @@ -408,7 +408,7 @@ def _resolve_reservation_ttl(logger: logging.Logger, credit_leases: Optional[Cre

Client mode is exempt: its TTL never reaches the server, it only tells the
local sweeper when to refund an unsettled hold, and the caller may well
want one that outlives an hour.
want one that outlives a day.
"""
if credit_leases is None:
return DEFAULT_RESERVATION_TTL
Expand All @@ -418,7 +418,7 @@ def _resolve_reservation_ttl(logger: logging.Logger, credit_leases: Optional[Cre
effective = MAX_RESERVATION_TTL - RESERVATION_TTL_SKEW_ALLOWANCE
if ttl > effective:
logger.warning(
f"credit_leases.default_reservation_ttl of {ttl}s is above the server's one hour cap; "
f"credit_leases.default_reservation_ttl of {ttl}s is above the server's 24 hour cap; "
f"server-mode holds will be clamped to {effective}s"
)
return effective
Expand Down
16 changes: 8 additions & 8 deletions tests/custom/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1842,13 +1842,13 @@ def test_an_integral_float_usage_reaches_the_preflight_unchanged(self):
)

def test_a_reservation_ttl_above_the_cap_is_clamped(self):
client = self._client(credit_leases=CreditLeaseConfig(default_reservation_ttl=7200.0))
client = self._client(credit_leases=CreditLeaseConfig(default_reservation_ttl=90000.0))
try:
# Short of the cap by the skew allowance, so a client running
# slightly fast still asks for something the server accepts.
self.assertEqual(client._reservation_ttl, MAX_RESERVATION_TTL - RESERVATION_TTL_SKEW_ALLOWANCE)
warning = " ".join(str(call.args[0]) for call in client.logger.warning.call_args_list)
self.assertIn("one hour cap", warning)
self.assertIn("24 hour cap", warning)
self.assertIn(
f"server-mode holds will be clamped to {MAX_RESERVATION_TTL - RESERVATION_TTL_SKEW_ALLOWANCE}s",
warning,
Expand Down Expand Up @@ -2293,11 +2293,11 @@ async def test_a_fractional_usage_rounds_the_hold_and_the_preflight_up(self):
assert kwargs["preflight"] == PreflightRequestBody(usage=3)

async def test_a_reservation_ttl_above_the_cap_is_clamped(self):
client = _async_server_client(credit_leases=CreditLeaseConfig(default_reservation_ttl=7200.0))
client = _async_server_client(credit_leases=CreditLeaseConfig(default_reservation_ttl=90000.0))
try:
assert client._reservation_ttl == MAX_RESERVATION_TTL - RESERVATION_TTL_SKEW_ALLOWANCE
warning = " ".join(str(call.args[0]) for call in client.logger.warning.call_args_list)
assert "one hour cap" in warning
assert "24 hour cap" in warning
assert (
f"server-mode holds will be clamped to {MAX_RESERVATION_TTL - RESERVATION_TTL_SKEW_ALLOWANCE}s"
in warning
Expand Down Expand Up @@ -2995,16 +2995,16 @@ async def test_a_lease_gated_check_reports_one_flag_check_event(self):
async def test_client_mode_keeps_a_reservation_ttl_past_the_server_cap(self):
client = _async_lease_client(
credit_leases=CreditLeaseConfig(
mode="client", default_lease_size=1000.0, default_reservation_ttl=7200.0
mode="client", default_lease_size=1000.0, default_reservation_ttl=90000.0
)
)
try:
# The TTL only drives the local sweeper here, so the server's cap
# does not apply and nothing is clamped or warned about.
assert client._reservation_ttl == 7200.0
assert client._lease_manager.resolve_config("bilcr_inference").reservation_ttl == 7200.0
assert client._reservation_ttl == 90000.0
assert client._lease_manager.resolve_config("bilcr_inference").reservation_ttl == 90000.0
warning = " ".join(str(call.args[0]) for call in client.logger.warning.call_args_list)
assert "one hour cap" not in warning
assert "24 hour cap" not in warning
finally:
await self._drain(client)

Expand Down
Loading