#975
Let checkout limits override a restored dump's limits on load_session
Summary
load_session restores the dump's own ResourceLimits and ignores the checkout(limits=...) config. The stubs say so, so this is a request rather than a bug report: please give the host a way to make the checkout's limits win on restore (or to set limits after load_session).
The reason: resource limits are host policy, not session state. A host that stores dumps between turns cannot today
- lower
max_memoryormax_feed_duration_secsin a release and have it apply to sessions that already exist, until each is reset; - treat limits as a per-deployment setting when the dumps live outside the host's control (e.g. in per-user storage). #873 rightly puts provenance and integrity on the caller, and we will sign our dumps, but even an authentic dump from last month carries last month's limits.
Reproduction (pydantic-monty 1.1.0, Python 3.13, Linux)
import asyncio, time
from pydantic_monty import AsyncMonty, MontyError
async def main():
async with AsyncMonty(min_processes=1) as pool:
async with pool.checkout(limits={"max_feed_duration_secs": 60.0, "max_memory": 400 * 2**20}) as s:
await s.feed_run("x = 1")
state = await s.dump()
async with AsyncMonty(min_processes=1) as pool:
async with pool.checkout(limits={"max_feed_duration_secs": 1.0, "max_memory": 10 * 2**20}) as s:
await s.load_session(state)
t = time.monotonic()
try:
await asyncio.wait_for(s.feed_run("while True:\n pass"), timeout=5)
except MontyError as exc:
print(f"stopped after {time.monotonic() - t:.1f}s: {type(exc).__name__}")
except asyncio.TimeoutError:
print("not stopped in 5s: the dump's 60s limit won over the checkout's 1s")
async with AsyncMonty(min_processes=1) as pool:
async with pool.checkout(limits={"max_feed_duration_secs": 5.0, "max_memory": 10 * 2**20}) as s:
await s.load_session(state)
try:
n = await s.feed_run("s = 'x' * (50 * 1024 * 1024)\nlen(s)")
print(f"allocated {n} bytes under a 10 MiB checkout limit: the dump's 400 MiB won")
except MontyError as exc:
print(f"refused: {type(exc).__name__}")
asyncio.run(main())Output:
not stopped in 5s: the dump's 60s limit won over the checkout's 1s
allocated 52428800 bytes under a 10 MiB checkout limit: the dump's 400 MiB wonA fresh session under the same 1 s / 10 MiB checkout stops the loop at 1.0 s with MontyRuntimeError. Same result on 0.0.23 with max_duration_secs.
What would help
Any of these would do:
checkout(limits=...)applies on top of a restored dump, with the dump's limits used only where the checkout passesNone. This seems like the least surprising default, since the checkout is what the host is asking for now.- A
load_session(state, limits=...)argument, or asession.set_limits(...)valid between feeds. - If the current behaviour is deliberate, a note in the
load_sessiondocstring saying that hosts who need limits as policy must reject or re-dump sessions whose stored limits differ, so it is a documented contract rather than a surprise.
The pool's request_timeout is a workable backstop for duration in the meantime, but there is nothing equivalent for memory.
Activity
0No activity yet.