Skip to content

Commit cb7ff7c

Browse files
authored
Inflate RAM usage when max session is reached (#24)
1 parent 03e8f17 commit cb7ff7c

2 files changed

Lines changed: 47 additions & 4 deletions

File tree

entrypoint.py

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import os
22
import shutil
3+
import threading
34
from argparse import ArgumentParser
45

56
import requests
7+
import numpy as np
68
import psutil
79
import panel as pn
810
from tornado.web import RequestHandler
@@ -12,6 +14,10 @@
1214
from aind_ephys_portal.panel.logging import list_gui_sessions, get_max_number_of_gui_sessions, LOG_DIR # noqa: F401
1315

1416

17+
TARGET_MEMORY_TRIGGER_PERCENT = 75
18+
TARGET_CLEAR_TMP_ARR_SECONDS = 30
19+
20+
1521
if LOG_DIR.is_dir():
1622
print(f"Cleaning up old log files in {LOG_DIR}...")
1723
shutil.rmtree(LOG_DIR)
@@ -31,20 +37,57 @@ def get_ecs_task_id():
3137
MAX_GUI_SESSIONS_PER_TASK = get_max_number_of_gui_sessions()
3238
print(f"Max GUI sessions per task: {MAX_GUI_SESSIONS_PER_TASK}")
3339

40+
_tmp_array_triggered = False
41+
_tmp_arr = None
42+
_tmp_arr_timer = None
43+
44+
45+
def _clear_tmp_arr():
46+
global _tmp_arr, _tmp_arr_timer
47+
print("Clearing temporary array to free up memory...")
48+
_tmp_arr = None
49+
_tmp_arr_timer = None
50+
print(f"tmp_arr cleared after {TARGET_CLEAR_TMP_ARR_SECONDS}s")
51+
3452
# 2. Health Check & Index Redirect
3553
class HealthHandler(RequestHandler):
3654
def get(self):
55+
global _tmp_arr, _tmp_arr_timer, _tmp_array_triggered
3756
mem = psutil.virtual_memory()
3857
# count number of GUI app sessions
3958
gui_sessions = list_gui_sessions()
4059
task_id = get_ecs_task_id()
41-
if mem.percent > 70 or len(gui_sessions) > MAX_GUI_SESSIONS_PER_TASK:
42-
self.set_status(503)
60+
if mem.percent > TARGET_MEMORY_TRIGGER_PERCENT:
61+
self.set_status(200)
62+
self.write(
63+
f"Busy (RAM Usage):\nMemory at {mem.percent}% - Num sessions: {len(gui_sessions)} "
64+
f"(max {MAX_GUI_SESSIONS_PER_TASK}) Task ID: {task_id}"
65+
)
66+
elif len(gui_sessions) > MAX_GUI_SESSIONS_PER_TASK:
67+
self.set_status(200)
68+
busy_msg = "(MAX SESSIONS EXCEEDED)"
69+
if _tmp_arr is not None:
70+
busy_msg += " (inflating memory)"
71+
elif _tmp_array_triggered:
72+
busy_msg += " (inflated memory released)"
4373
self.write(
44-
f"Busy:\nMemory at {mem.percent}% - Num sessions: {len(gui_sessions)} "
74+
f"Busy {busy_msg}:\nMemory at {mem.percent}% - Num sessions: {len(gui_sessions)} "
4575
f"(max {MAX_GUI_SESSIONS_PER_TASK}) Task ID: {task_id}"
4676
)
77+
# inflate RAM once per threshold-exceeded event so ECS spawns a new task
78+
if _tmp_arr is None and not _tmp_array_triggered:
79+
_tmp_array_triggered = True
80+
total_memory = psutil.virtual_memory().total
81+
used_memory = psutil.virtual_memory().used
82+
target_memory = total_memory * TARGET_MEMORY_TRIGGER_PERCENT / 100
83+
array_size = int((target_memory - used_memory) / 8) # assuming float64 (8 bytes)
84+
_tmp_arr = np.ones(array_size, dtype=np.float64)
85+
print(f"Inflated memory with array of size {array_size} to trigger ECS scaling")
86+
_tmp_arr_timer = threading.Timer(TARGET_CLEAR_TMP_ARR_SECONDS, _clear_tmp_arr)
87+
_tmp_arr_timer.daemon = True
88+
_tmp_arr_timer.start()
4789
else:
90+
_tmp_array_triggered = False
4891
self.set_status(200)
4992
self.write(
5093
f"Healthy:\nMemory at {mem.percent}% - Num sessions: {len(gui_sessions)} "

src/aind_ephys_portal/panel/logging.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def list_gui_sessions():
8585

8686
def get_max_number_of_gui_sessions():
8787
# Estimate number of sessions per worker for health check.
88-
SESSION_AVG_RAM_USAGE_GB = 2.5
88+
SESSION_AVG_RAM_USAGE_GB = 2
8989
TOTAL_RAM_GB = psutil.virtual_memory().total / (1024**3)
9090
MAX_SESSIONS_PER_WORKER = int(np.floor(TOTAL_RAM_GB / SESSION_AVG_RAM_USAGE_GB))
9191

0 commit comments

Comments
 (0)