初始化 HyperNode-AI 控制面。
包含节点账本、每日清算,以及 Ubuntu 交互式部署脚本。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
"""多实例定时任务互斥。锁有过期时间,持有进程异常退出后其他实例仍能继续。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import socket
|
||||
from datetime import timedelta
|
||||
|
||||
from sqlalchemy import update
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
|
||||
from app.clock import utcnow
|
||||
from app.database import session_scope
|
||||
from app.models import SchedulerLock
|
||||
|
||||
OWNER = f"{socket.gethostname()}:{os.getpid()}"
|
||||
|
||||
|
||||
def acquire_lock(name: str, ttl: timedelta) -> bool:
|
||||
now = utcnow()
|
||||
until = now + ttl
|
||||
try:
|
||||
with session_scope() as session:
|
||||
lock = session.get(SchedulerLock, name)
|
||||
if lock is None:
|
||||
session.add(SchedulerLock(name=name, locked_until=until, owner=OWNER))
|
||||
try:
|
||||
session.flush()
|
||||
except IntegrityError:
|
||||
session.rollback()
|
||||
return False
|
||||
return True
|
||||
updated = session.execute(
|
||||
update(SchedulerLock)
|
||||
.where(SchedulerLock.name == name)
|
||||
.where(SchedulerLock.locked_until <= now)
|
||||
.values(locked_until=until, owner=OWNER)
|
||||
)
|
||||
return updated.rowcount == 1
|
||||
except IntegrityError:
|
||||
return False
|
||||
Reference in New Issue
Block a user