refactor: 使用假端口实现调度器单例控制

- 恢复 agentmain.py 到原始状态
- launch.pyw 使用端口 65432 检测单例
- 避免重复启动调度器实例
This commit is contained in:
Liang Jiaqing
2026-02-14 10:17:26 +08:00
parent cf8c191ae9
commit ab48b35ca9
2 changed files with 13 additions and 28 deletions

View File

@@ -110,33 +110,8 @@ class GeneraticAgent:
if self.handler is not None: self.handler.code_stop_signal.append(1) if self.handler is not None: self.handler.code_stop_signal.append(1)
def acquire_singleton_lock():
"""确保只有一个调度器实例运行"""
lock_file = './temp/scheduler.lock'
os.makedirs('./temp', exist_ok=True)
if os.name == 'nt': # Windows
import msvcrt
try:
lock_fd = open(lock_file, 'w')
msvcrt.locking(lock_fd.fileno(), msvcrt.LK_NBLCK, 1)
return lock_fd
except:
print('[Scheduler] Another instance is already running')
sys.exit(0)
else: # Unix/Linux
import fcntl
try:
lock_fd = open(lock_file, 'w')
fcntl.flock(lock_fd.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
return lock_fd
except:
print('[Scheduler] Another instance is already running')
sys.exit(0)
if __name__ == '__main__': if __name__ == '__main__':
from datetime import datetime from datetime import datetime
lock_fd = acquire_singleton_lock() # 获取单例锁
agent = GeneraticAgent() agent = GeneraticAgent()
threading.Thread(target=agent.run, daemon=True).start() threading.Thread(target=agent.run, daemon=True).start()
def drain(dq, tag): def drain(dq, tag):

View File

@@ -92,9 +92,19 @@ if __name__ == '__main__':
else: print('[Launch] Telegram Bot disabled (--no-tg)') else: print('[Launch] Telegram Bot disabled (--no-tg)')
if not args.no_scheduler: if not args.no_scheduler:
# 使用假端口检测单例
import socket
scheduler_port = 65432
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1', scheduler_port))
sock.listen(1)
# 绑定成功,启动调度器
scheduler_proc = subprocess.Popen([sys.executable, "agentmain.py"], creationflags=subprocess.CREATE_NO_WINDOW if os.name=='nt' else 0) scheduler_proc = subprocess.Popen([sys.executable, "agentmain.py"], creationflags=subprocess.CREATE_NO_WINDOW if os.name=='nt' else 0)
atexit.register(scheduler_proc.kill) atexit.register(lambda: (scheduler_proc.kill(), sock.close()))
print('[Launch] Task Scheduler started') print('[Launch] Task Scheduler started')
except OSError:
print('[Launch] Task Scheduler already running (port occupied)')
else: print('[Launch] Task Scheduler disabled (--no-scheduler)') else: print('[Launch] Task Scheduler disabled (--no-scheduler)')
monitor_thread = threading.Thread(target=idle_monitor, daemon=True) monitor_thread = threading.Thread(target=idle_monitor, daemon=True)