e6d1ebd152
gates / gates (push) Successful in 28s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
54 lines
3.9 KiB
Python
54 lines
3.9 KiB
Python
#!/usr/bin/env python3
|
|
"""fg_grim_mem.py — Grimmory's memory rows on 9202 (checklist 5.2 burst, 5.4 self-sizing), behind the family gate.
|
|
5.2: the household's heaviest ordinary act — a burst of book uploads (40 EPUBs through the app's own upload API, the
|
|
library re-reading each) — while grimmory's own cgroup is sampled every second (anon, oom_kill, restarts).
|
|
5.4: does the heap size itself from the limit? The image's JAVA_TOOL_OPTIONS carry MaxRAMPercentage=60; the JVM's own
|
|
answer (MaxHeapSize) is read at three container limits with the SAME image and options (`docker run --rm -m`, no app).
|
|
Evidence: $EV/B/box/grim-mem.txt."""
|
|
import json, os, secrets, subprocess, sys, tempfile, threading, time
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
from fg import * # noqa
|
|
import upgrade_fixtures_box as fixtures
|
|
GM = fixtures.FIXTURES["grimmory"]
|
|
EVD = f"{w.EV}/B/box"; log = open(f"{EVD}/grim-mem.txt", "a", buffering=1)
|
|
def say(*a):
|
|
w.say(*a); log.write(" ".join(map(str, a)) + "\n")
|
|
w.login()
|
|
t = json.load(open(w.SC + "/seed-tokens-fg.json"))["grimmory"]
|
|
say(f"##### grimmory memory on 9202 — {time.strftime('%FT%TZ', time.gmtime())} | limit", w.guest("docker inspect grimmory --format '{{.HostConfig.Memory}}'").strip())
|
|
w.guest("cat > /root/gm-s.sh <<'SEOF'\nid=$(docker ps -q --no-trunc --filter name=^grimmory$); cg=/sys/fs/cgroup/system.slice/docker-$id.scope; : > /root/gm-mem.csv\n"
|
|
"while [ ! -f /root/gm-mem.stop ]; do echo \"$(date +%s),$(awk '$1==\"anon\"{print $2}' $cg/memory.stat),$(awk '$1==\"oom_kill\"{print $2}' $cg/memory.events),$(cat $cg/memory.max),$(docker inspect -f '{{.RestartCount}}' $id)\" >> /root/gm-mem.csv; sleep 1; done\nSEOF\n"
|
|
"rm -f /root/gm-mem.stop; (nohup sh /root/gm-s.sh >/dev/null 2>&1 &)")
|
|
time.sleep(5)
|
|
code, tok = GM._token(w, "library", t["user"], t["pw"])
|
|
auth = ["-H", f"Authorization: Bearer {tok}"]
|
|
rc, code, out = w.app_curl("library", "/api/v1/libraries", *auth)
|
|
lib = json.loads(out)[0]; lid, pid = lib["id"], lib["paths"][0]["id"]
|
|
t0 = time.time(); codes = {}
|
|
for i in range(40):
|
|
fn = tempfile.mktemp(suffix=".epub"); open(fn, "wb").write(GM._epub(f"Felhom Burst {i:02d} " + secrets.token_hex(3)))
|
|
rc, c, _ = w.app_curl("library", "/api/v1/files/upload", *auth, "-F", f"file=@{fn};type=application/epub+zip",
|
|
"-F", f"libraryId={lid}", "-F", f"pathId={pid}", method="POST")
|
|
os.unlink(fn); codes[c] = codes.get(c, 0) + 1
|
|
say(f"5.2 burst: 40 EPUB uploads through the app's own API in {time.time()-t0:.1f} s: codes {codes}")
|
|
n = 0
|
|
for _ in range(36):
|
|
rc, c, out = w.app_curl("library", "/api/v1/books", *auth)
|
|
try: n = len(json.loads(out))
|
|
except Exception: n = -1
|
|
if n >= 41: break
|
|
time.sleep(5)
|
|
say(f" the library lists {n} books after the burst ({time.time()-t0:.0f} s from its start); sampling 120 s more")
|
|
time.sleep(120)
|
|
w.guest("touch /root/gm-mem.stop"); time.sleep(2)
|
|
rows = [r.split(",") for r in w.guest("cat /root/gm-mem.csv").split() if r.count(",") == 4]
|
|
lim = int(rows[0][3]); peak = max(int(r[1]) for r in rows)
|
|
say(f"5.2 grimmory, {len(rows)} samples (1/s) across the burst: peak anon {peak/1048576:.1f} MiB = {100*peak/lim:.1f} % of {lim//1048576}M; "
|
|
f"oom_kill {max(int(r[2]) for r in rows)}; restarts {max(int(r[4]) for r in rows)}")
|
|
open(f"{EVD}/grim-mem-burst.csv", "w").write("epoch,anon,oom_kill,limit,restarts\n" + "\n".join(",".join(r) for r in rows) + "\n")
|
|
w.guest("rm -f /root/gm-s.sh /root/gm-mem.csv /root/gm-mem.stop")
|
|
img = w.guest("docker inspect grimmory --format '{{.Config.Image}}'").strip()
|
|
for m in ("768m", "1024m", "1536m"):
|
|
out = w.guest(f"docker run --rm -m {m} --memory-swap {m} --entrypoint java {img} -XX:+PrintFlagsFinal -version 2>/dev/null | grep -E ' MaxHeapSize | MaxRAMPercentage '")
|
|
say(f"5.4 {img} at a {m} container limit (the image's own JAVA_TOOL_OPTIONS): " + " | ".join(" ".join(l.split()) for l in out.strip().splitlines()))
|