Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -293,6 +293,7 @@ gc.enable()
|
|
| 293 |
gc.set_threshold(700, 10, 10)
|
| 294 |
|
| 295 |
passive_gc_active = True
|
|
|
|
| 296 |
|
| 297 |
def force_gc():
|
| 298 |
"""Force aggressive garbage collection"""
|
|
@@ -322,9 +323,24 @@ def passive_gc_daemon():
|
|
| 322 |
except Exception as e:
|
| 323 |
logger.error(f"[PASSIVE-GC] Error: {e}")
|
| 324 |
|
| 325 |
-
|
| 326 |
-
|
| 327 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 328 |
|
| 329 |
def nuclear_ram_clear():
|
| 330 |
"""NUCLEAR option: Clear all Python caches and force full GC"""
|
|
@@ -903,6 +919,13 @@ class ZeroEngine:
|
|
| 903 |
self.auto_cleanup_thread.start()
|
| 904 |
logger.info("[IDLE] Idle monitor started (20s timeout)")
|
| 905 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 906 |
def update_activity(self):
|
| 907 |
"""Update last activity timestamp"""
|
| 908 |
self.last_activity = time.time()
|
|
@@ -1408,7 +1431,10 @@ kernel = ZeroEngine()
|
|
| 1408 |
# Session ID for token tracking
|
| 1409 |
session_id = "turtle170"
|
| 1410 |
|
| 1411 |
-
with gr.Blocks(title="ZeroEngine V0.2"
|
|
|
|
|
|
|
|
|
|
| 1412 |
gr.LoginButton()
|
| 1413 |
# Header with Token Display
|
| 1414 |
with gr.Row():
|
|
@@ -1639,6 +1665,48 @@ with gr.Blocks(title="ZeroEngine V0.2", css=CUSTOM_CSS) as demo:
|
|
| 1639 |
|
| 1640 |
# --- LAUNCH ---
|
| 1641 |
if __name__ == "__main__":
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1642 |
demo.queue(max_size=20).launch(
|
| 1643 |
server_name="0.0.0.0",
|
| 1644 |
server_port=7861,
|
|
|
|
| 293 |
gc.set_threshold(700, 10, 10)
|
| 294 |
|
| 295 |
passive_gc_active = True
|
| 296 |
+
passive_gc_thread = None
|
| 297 |
|
| 298 |
def force_gc():
|
| 299 |
"""Force aggressive garbage collection"""
|
|
|
|
| 323 |
except Exception as e:
|
| 324 |
logger.error(f"[PASSIVE-GC] Error: {e}")
|
| 325 |
|
| 326 |
+
def start_passive_gc():
|
| 327 |
+
"""Start passive garbage collector thread"""
|
| 328 |
+
global passive_gc_thread
|
| 329 |
+
if passive_gc_thread is None or not passive_gc_thread.is_alive():
|
| 330 |
+
passive_gc_thread = threading.Thread(target=passive_gc_daemon, daemon=True)
|
| 331 |
+
passive_gc_thread.start()
|
| 332 |
+
logger.info("[PASSIVE-GC] Background garbage collector started (30s intervals)")
|
| 333 |
+
|
| 334 |
+
def stop_passive_gc():
|
| 335 |
+
"""Stop passive garbage collector thread gracefully"""
|
| 336 |
+
global passive_gc_active, passive_gc_thread
|
| 337 |
+
passive_gc_active = False
|
| 338 |
+
if passive_gc_thread and passive_gc_thread.is_alive():
|
| 339 |
+
passive_gc_thread.join(timeout=2.0)
|
| 340 |
+
logger.info("[PASSIVE-GC] Background garbage collector stopped")
|
| 341 |
+
|
| 342 |
+
# Start the passive GC thread
|
| 343 |
+
start_passive_gc()
|
| 344 |
|
| 345 |
def nuclear_ram_clear():
|
| 346 |
"""NUCLEAR option: Clear all Python caches and force full GC"""
|
|
|
|
| 919 |
self.auto_cleanup_thread.start()
|
| 920 |
logger.info("[IDLE] Idle monitor started (20s timeout)")
|
| 921 |
|
| 922 |
+
def stop_idle_monitor(self):
|
| 923 |
+
"""Stop idle monitor thread gracefully"""
|
| 924 |
+
if self.auto_cleanup_thread and self.auto_cleanup_thread.is_alive():
|
| 925 |
+
# Set a flag to stop the monitor (would need to add shared flag for proper cleanup)
|
| 926 |
+
# For now, we'll let it be a daemon thread that exits with the process
|
| 927 |
+
logger.info("[IDLE] Idle monitor will stop on process exit")
|
| 928 |
+
|
| 929 |
def update_activity(self):
|
| 930 |
"""Update last activity timestamp"""
|
| 931 |
self.last_activity = time.time()
|
|
|
|
| 1431 |
# Session ID for token tracking
|
| 1432 |
session_id = "turtle170"
|
| 1433 |
|
| 1434 |
+
with gr.Blocks(title="ZeroEngine V0.2") as demo:
|
| 1435 |
+
demo_css = CUSTOM_CSS
|
| 1436 |
+
if hasattr(demo, 'css'):
|
| 1437 |
+
demo.css = demo_css
|
| 1438 |
gr.LoginButton()
|
| 1439 |
# Header with Token Display
|
| 1440 |
with gr.Row():
|
|
|
|
| 1665 |
|
| 1666 |
# --- LAUNCH ---
|
| 1667 |
if __name__ == "__main__":
|
| 1668 |
+
import atexit
|
| 1669 |
+
import signal
|
| 1670 |
+
|
| 1671 |
+
def cleanup_on_exit():
|
| 1672 |
+
"""Cleanup function called on application exit"""
|
| 1673 |
+
logger.info("[CLEANUP] Starting graceful shutdown...")
|
| 1674 |
+
|
| 1675 |
+
# Stop passive GC
|
| 1676 |
+
stop_passive_gc()
|
| 1677 |
+
|
| 1678 |
+
# Cleanup kernel resources
|
| 1679 |
+
if kernel and kernel.llm:
|
| 1680 |
+
try:
|
| 1681 |
+
del kernel.llm
|
| 1682 |
+
kernel.llm = None
|
| 1683 |
+
logger.info("[CLEANUP] Model unloaded")
|
| 1684 |
+
except Exception as e:
|
| 1685 |
+
logger.error(f"[CLEANUP] Model cleanup error: {e}")
|
| 1686 |
+
|
| 1687 |
+
# Final garbage collection
|
| 1688 |
+
try:
|
| 1689 |
+
for _ in range(3):
|
| 1690 |
+
gc.collect(2)
|
| 1691 |
+
logger.info("[CLEANUP] Final GC complete")
|
| 1692 |
+
except Exception as e:
|
| 1693 |
+
logger.error(f"[CLEANUP] Final GC error: {e}")
|
| 1694 |
+
|
| 1695 |
+
logger.info("[CLEANUP] Shutdown complete")
|
| 1696 |
+
|
| 1697 |
+
# Register cleanup functions
|
| 1698 |
+
atexit.register(cleanup_on_exit)
|
| 1699 |
+
|
| 1700 |
+
def signal_handler(signum, frame):
|
| 1701 |
+
"""Handle shutdown signals gracefully"""
|
| 1702 |
+
logger.info(f"[CLEANUP] Received signal {signum}")
|
| 1703 |
+
cleanup_on_exit()
|
| 1704 |
+
import sys
|
| 1705 |
+
sys.exit(0)
|
| 1706 |
+
|
| 1707 |
+
signal.signal(signal.SIGTERM, signal_handler)
|
| 1708 |
+
signal.signal(signal.SIGINT, signal_handler)
|
| 1709 |
+
|
| 1710 |
demo.queue(max_size=20).launch(
|
| 1711 |
server_name="0.0.0.0",
|
| 1712 |
server_port=7861,
|