|
11 | 11 | import panel as pn |
12 | 12 | from tornado.web import RequestHandler |
13 | 13 |
|
14 | | -# Start tracemalloc as early as possible so allocation tracebacks include the |
15 | | -# session-loading code paths. Frame depth 10 is enough to identify the call site |
16 | | -# inside spikeinterface/zarr/fsspec without blowing up memory overhead. |
17 | | -tracemalloc.start(10) |
18 | | -_tracemalloc_baseline = tracemalloc.take_snapshot() |
| 14 | +# tracemalloc is OFF by default. Recording a per-allocation Python traceback |
| 15 | +# adds non-trivial CPU overhead per allocation; on a Panel + spikeinterface |
| 16 | +# + zarr workload that slowed Tornado enough for ECS health checks to time |
| 17 | +# out, producing exit-137 restart loops. Enable only on diagnostic deploys: |
| 18 | +# TRACEMALLOC_ENABLED=1 (and optionally TRACEMALLOC_DEPTH, default 4) |
| 19 | +_TRACEMALLOC_ENABLED = os.environ.get("TRACEMALLOC_ENABLED", "0").lower() in ("1", "true", "yes") |
| 20 | +_tracemalloc_baseline = None |
| 21 | +if _TRACEMALLOC_ENABLED: |
| 22 | + _tm_depth = int(os.environ.get("TRACEMALLOC_DEPTH", "4")) |
| 23 | + tracemalloc.start(_tm_depth) |
| 24 | + _tracemalloc_baseline = tracemalloc.take_snapshot() |
| 25 | + print(f"tracemalloc ENABLED with frame depth {_tm_depth}") |
| 26 | +else: |
| 27 | + print("tracemalloc DISABLED (set TRACEMALLOC_ENABLED=1 to enable)") |
19 | 28 |
|
20 | 29 | # 1. Run setup (replaces --setup flag) |
21 | 30 | from aind_ephys_portal.setup import * # noqa: F401,F403,E402 |
|
33 | 42 | TARGET_INFLATE_DELAY_SECONDS = 90 |
34 | 43 |
|
35 | 44 | # Recycle signal: when a task is sitting idle (0 GUI sessions) but its RAM |
36 | | -# stays above this percent, /health returns 503 so the ALB deregisters it and |
37 | | -# the ECS service scheduler replaces it. Baseline (no sessions, fresh start) |
38 | | -# is ~10%, so 40% means tolerating ~30 points of accumulated residue before |
39 | | -# recycling. Only triggers with 0 sessions, so user sessions are never cut. |
40 | | -RECYCLE_RAM_PERCENT_WHEN_IDLE = 40 |
| 45 | +# stays above this percent, /health returns 503 so the ALB deregisters it |
| 46 | +# and the ECS service scheduler replaces it. Overridable via env var so we |
| 47 | +# can tune without redeploys once we re-baseline post-rollback. Only |
| 48 | +# triggers with 0 sessions, so user sessions are never cut. |
| 49 | +RECYCLE_RAM_PERCENT_WHEN_IDLE = int(os.environ.get("RECYCLE_RAM_PERCENT_WHEN_IDLE", "50")) |
41 | 50 |
|
42 | 51 |
|
43 | 52 | if LOG_DIR.is_dir(): |
@@ -212,15 +221,18 @@ def get(self): |
212 | 221 |
|
213 | 222 | # 4) tracemalloc top allocators since boot baseline |
214 | 223 | tm_lines = [] |
215 | | - try: |
216 | | - current = tracemalloc.take_snapshot() |
217 | | - stats = current.compare_to(_tracemalloc_baseline, "lineno")[:25] |
218 | | - for stat in stats: |
219 | | - tm_lines.append( |
220 | | - f" +{stat.size_diff/1024/1024:7.2f} MiB ({stat.count_diff:+d} blocks) {stat.traceback[0]}" |
221 | | - ) |
222 | | - except Exception as e: |
223 | | - tm_lines.append(f"tracemalloc unavailable: {e}") |
| 224 | + if not _TRACEMALLOC_ENABLED: |
| 225 | + tm_lines.append("tracemalloc disabled (set TRACEMALLOC_ENABLED=1 to enable)") |
| 226 | + else: |
| 227 | + try: |
| 228 | + current = tracemalloc.take_snapshot() |
| 229 | + stats = current.compare_to(_tracemalloc_baseline, "lineno")[:25] |
| 230 | + for stat in stats: |
| 231 | + tm_lines.append( |
| 232 | + f" +{stat.size_diff/1024/1024:7.2f} MiB ({stat.count_diff:+d} blocks) {stat.traceback[0]}" |
| 233 | + ) |
| 234 | + except Exception as e: |
| 235 | + tm_lines.append(f"tracemalloc error: {e}") |
224 | 236 |
|
225 | 237 | self.set_header("Content-Type", "text/plain; charset=utf-8") |
226 | 238 | out = [ |
|
0 commit comments