main_server.py가 중복 실행되면서 좀비 프로세스가 수행되는 오류 해결, process_tracker.py가 감시하면서 할당되지 않은 pid가 존재하면 좀비프로세스로 판단하여 kill
This commit is contained in:
78
modules/utils/process_tracker.py
Normal file
78
modules/utils/process_tracker.py
Normal file
@@ -0,0 +1,78 @@
|
||||
import os
|
||||
import time
|
||||
|
||||
class ProcessTracker:
|
||||
FILE_PATH = "pids.txt"
|
||||
|
||||
@staticmethod
|
||||
def register(name):
|
||||
"""현재 프로세스의 PID와 이름을 기록"""
|
||||
pid = os.getpid()
|
||||
entry = f"{pid}: {name} (Started: {time.strftime('%Y-%m-%d %H:%M:%S')})\n"
|
||||
|
||||
try:
|
||||
# 파일이 없으면 생성, 있으면 추가
|
||||
# 단, main_server 시작 시 초기화하는 것이 좋음
|
||||
with open(ProcessTracker.FILE_PATH, "a", encoding="utf-8") as f:
|
||||
f.write(entry)
|
||||
print(f"📌 Process Registered: {name} (PID: {pid})")
|
||||
except Exception as e:
|
||||
print(f"⚠️ Failed to register process: {e}")
|
||||
|
||||
@staticmethod
|
||||
def check_and_kill_zombies():
|
||||
"""
|
||||
pids.txt에 기록된 이전 프로세스들이 구동 중이라면 강제 종료.
|
||||
서버 시작 시 1회 호출하여 좀비 프로세스를 정리함.
|
||||
"""
|
||||
if not os.path.exists(ProcessTracker.FILE_PATH):
|
||||
return
|
||||
|
||||
print("🔍 Checking for zombie processes...")
|
||||
try:
|
||||
import psutil
|
||||
current_pid = os.getpid()
|
||||
|
||||
with open(ProcessTracker.FILE_PATH, "r", encoding="utf-8") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
killed_count = 0
|
||||
for line in lines:
|
||||
if ":" not in line or "Running Processes" in line:
|
||||
continue
|
||||
|
||||
try:
|
||||
pid_str = line.split(":")[0].strip()
|
||||
pid = int(pid_str)
|
||||
|
||||
if pid == current_pid:
|
||||
continue
|
||||
|
||||
if psutil.pid_exists(pid):
|
||||
proc = psutil.Process(pid)
|
||||
proc_name = proc.name()
|
||||
|
||||
# Python 프로세스만 타겟
|
||||
if "python" in proc_name.lower():
|
||||
print(f"💀 Killing Zombie Process: {pid} ({line.strip()})")
|
||||
proc.kill()
|
||||
killed_count += 1
|
||||
except (ValueError, psutil.NoSuchProcess, psutil.AccessDenied):
|
||||
continue
|
||||
|
||||
if killed_count > 0:
|
||||
print(f"✅ Cleaned up {killed_count} zombie processes.")
|
||||
# 파일 초기화
|
||||
ProcessTracker.clear()
|
||||
|
||||
except Exception as e:
|
||||
print(f"⚠️ Failed to kill zombies: {e}")
|
||||
|
||||
@staticmethod
|
||||
def clear():
|
||||
"""PID 파일 초기화"""
|
||||
try:
|
||||
with open(ProcessTracker.FILE_PATH, "w", encoding="utf-8") as f:
|
||||
f.write(f"--- Running Processes (Last Update: {time.strftime('%Y-%m-%d %H:%M:%S')}) ---\n")
|
||||
except:
|
||||
pass
|
||||
Reference in New Issue
Block a user