Files
magicwang1111-ComfyUI-Accou…/utils/task_sessions.py
T

75 lines
3.2 KiB
Python

from aiohttp import web
class TaskSessions:
"""Delegate the executing queue owner's session to a node subprocess."""
def __init__(self, server, users_db, jwt_auth, scheduler):
self.server = server
self.users_db = users_db
self.jwt_auth = jwt_auth
self.scheduler = scheduler
def _local_owner(self, prompt_id):
queue = self.server.prompt_queue
with queue.mutex:
for item in queue.currently_running.values():
if len(item) >= 7 and item[1] == prompt_id:
return item[6]
return None
def environment(self, prompt_id):
owner = self._local_owner(prompt_id)
if not owner:
raise ValueError("无法取得当前执行任务的已认证账号,不能调用视频服务。")
user_id, user = self.users_db.get_user(user_id=owner)
if user_id != owner or not user:
raise ValueError("当前任务所属账号已不存在。")
token = self.jwt_auth.create_access_token(
{"id": owner, "username": user["username"], "am_task": prompt_id},
expire_minutes=120,
)
return {
"COMFY_TASK_TOKEN": token,
"COMFY_TASK_BASE_URL": f"http://127.0.0.1:{self.server.port}",
}
async def authorize(self, request, claims):
prompt_id = claims["am_task"]
if self.scheduler:
job = self.scheduler.get_job(prompt_id)
owner = job["owner_id"] if job and job["status"] == "running" else None
else:
owner = self._local_owner(prompt_id)
if not owner or owner != claims["id"]:
raise web.HTTPUnauthorized(reason="Parent task is no longer running")
path = request.path.removeprefix("/api")
allowed = (
request.method == "GET" and (
path in {"/object_info", "/view", "/queue"}
or path.startswith("/history/")
)
or request.method == "POST" and path in {"/upload/image", "/prompt"}
)
if not allowed:
raise web.HTTPForbidden(reason="Task session cannot access this endpoint")
if request.method != "POST" or path != "/prompt":
return
if not self.scheduler or len(self.scheduler.worker_ports()) < 2:
raise web.HTTPConflict(reason="Video child task requires another scheduler worker")
payload = await request.json()
resource = self.scheduler.classify_item((0, "", payload.get("prompt", {})))
_, user = self.users_db.get_user(user_id=owner)
limit = (
self.scheduler.admin_concurrency_limit if user.get("admin") else
self.scheduler.resource_concurrency_limits.get(
resource, self.scheduler.max_concurrent_jobs_per_user
)
)
active = self.scheduler.running_jobs(owner)
if limit and sum(job["resource_class"] == resource for job in active) >= limit:
raise web.HTTPConflict(reason="Account concurrency is full; parent Agent is waiting for a video child task")
if not set(self.scheduler.idle_worker_ports(resource)) - {self.server.port}:
raise web.HTTPConflict(reason="No free scheduler worker for the video child task")