Skip to content

Let hosts install a custom memory probe - #740

Open
tontinton wants to merge 1 commit into
pydantic:mainfrom
tontinton:host-memory-probe
Open

Let hosts install a custom memory probe#740
tontinton wants to merge 1 commit into
pydantic:mainfrom
tontinton:host-memory-probe

Conversation

@tontinton

@tontinton tontinton commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

The tracker reads memory from the process-wide LIVE_MEMORY/BASELINE_MEMORY pair, which fits one interpreter per monty-alloc worker.

A host that embeds the interpreter in-process and runs several at once cannot keep that accounting straight: arming the shared baseline for one run forgives another run's usage, and the limit silently stops enforcing.

set_memory_probe points the read at the host's own accounting instead, say a thread-local live count fed by its global allocator, installed once like a global allocator.

Enforcement is unchanged: the tracker still checks max_memory at checkpoints, and workers never call the new API so they keep the default read.


Summary by cubic

Allows hosts to install a custom memory probe to replace the default LIVE_MEMORY - BASELINE_MEMORY read, so concurrent in-process interpreters enforce max_memory independently. Previously, shared counters rebased each other and could silently disable enforcement under concurrent load; default behavior remains unchanged unless a host installs a probe.

Review and rollout

  • Exposes set_memory_probe in monty-types; installs once via OnceLock, a second install returns "memory probe already installed".
  • probe_memory() delegates to the installed probe or falls back to LIVE_MEMORY - BASELINE_MEMORY.
  • Docs for ResourceLimits::max_memory and ResourceTracker::new now state enforcement requires monty-alloc or a probe.
  • If you embed multiple interpreters in one process, install the probe once at startup; no action needed for worker-per-interpreter setups using monty-alloc.

Written for commit 38f9d7a. Summary will update on new commits.

Review in cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 3 files

Re-trigger cubic

@codecov

codecov Bot commented Aug 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 50.00000% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/monty-types/src/resource.rs 50.00% 4 Missing ⚠️

📢 Thoughts on this report? Let us know!

The tracker reads memory from the process-wide `LIVE_MEMORY`/`BASELINE_MEMORY` pair, which fits one interpreter per `monty-alloc` worker.

A host that embeds the interpreter in-process and runs several at once cannot keep that accounting straight: arming the shared baseline for one run forgives another run's usage, and the limit silently stops enforcing.

`set_memory_probe` points the read at the host's own accounting instead, say a thread-local live count fed by its global allocator, installed once like a global allocator.

Enforcement is unchanged: the tracker still checks `max_memory` at checkpoints, and workers never call the new API so they keep the default read.
@codspeed-hq

codspeed-hq Bot commented Aug 13, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 36 untouched benchmarks
⏩ 16 skipped benchmarks1


Comparing tontinton:host-memory-probe (5aa07a1) with main (140d12b)

Open in CodSpeed

Footnotes

  1. 16 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@samuelcolvin

Copy link
Copy Markdown
Member

Sorry, I don't see how this works. Please can you (a human) explain how it works and how it would be used.

@tontinton

tontinton commented Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

I'm running monty in-process, and since the tracker started reading LIVE_MEMORY/BASELINE_MEMORY, max_memory is never enforced: nothing updates those counters unless monty-alloc is the global allocator, and I can't use monty-alloc because it kills the whole process.

So I want to run a separate thread per monty interpreter via a simple counting #[global_allocator] that updates a thread-local counter, and then setting it via set_memory_probe, skipping the LIVE_MEMORY - BASELINE_MEMORY check you do.

Honestly this is not the best solution, but this is the fastest solution to my problem. And the problem is real, wanting to run monty not as a separate process makes sense. Maybe there are much better solutions, would love to hear from you too.

@samuelcolvin

@samuelcolvin

Copy link
Copy Markdown
Member

Why do you want/need to run monty in the same progress?

@tontinton

tontinton commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

Why do you want/need to run monty in the same progress?

I use monty as the backend for my code_execution tool in my agent harness, and the agent can run it inside batch / inside subagents, starting to manage a bunch of subprocesses when unnecessary is annoying and more complex.

I can manage though, if you say you don't want to ever support the use case of having multiple monty interpreters shared in a process. Just wanted to shoot a shot at fixing the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants