Skip to content

Conversation

@KoalaBryson
Copy link
Collaborator

Change-Id: I1dbd079817dbb351eba8f7ce2e72121b163a6f05

@KoalaBryson KoalaBryson force-pushed the comfyui-multi-user branch 9 times, most recently from bfeaec8 to 6b5bb81 Compare February 2, 2026 02:48
Change-Id: I1dbd079817dbb351eba8f7ce2e72121b163a6f05
1. JWT 方式:从 Art-Comfy-User header 提取(网关解析 JWT 后注入)
2. Basic Auth 方式:从 Authorization: Basic header 中解析 username

通过 ENABLE_COMFYUI_USER 环境变量控制:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

相比于 ENABLE_COMFYUI_USER,ENABLE_MULTI_USER 是不是会好一些?

return decorated_function


def user_optional(func):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

user_optional 是有必要的吗?在哪里会用到呢?

return None


def user_required(func):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 模块名:user_auth => user_identity.py
  2. 函数名:user_required => identify_user # 明确表达:从多租户环境中识别用户
  3. 函数名:user_optional => identify_user_or_default

identify (识别) 比 auth (认证) 更准确,因为它描述的是“你是谁”,而不是“你的密码对不对”。
user_identity 作为一个模块名,清晰地告诉别人这里是处理用户身份识别逻辑的地方。
or_default 后缀比 optional 更清楚地说明了“如果获取不到会发生什么”(即:降级到默认用户)。


def _register_prompt_handler(self):
@self.bp.route("/prompt", methods=["POST"])
@user_required
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果这个需要每个 handler 都定义一个,是不是可以放到 @self.bp.before_request 里?

}
}), 400

# 注入user_id到extra_data
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

中英文之前有空格

client_id = ""

# 注入user_id到extra_data
user_id = getattr(g, 'user_id', 'default')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

serverless_handler 有必要修改么?webui 是不是不会走到这里?

from services.process.websocket.websocket_manager import ws_manager
from utils.logger import log
from utils.user_auth import extract_user_from_header
import constants
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

constants 看起来没被用到?

)
return user_id

return 'system'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里返回 'system' 有什么特殊的考量吗?
其他的都是 getattr(g, 'user_id', 'default')

return self._history_helper.get_history(user_id, max_items, offset)

@staticmethod
def _extract_prompt_id_from_body(prompt_body: dict, fallback_id: str) -> str:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

在此之前,prompt_id 和 task_id 是一样的吗?

return self._history_helper.get_history(user_id, max_items, offset)

@staticmethod
def _extract_prompt_id_from_body(prompt_body: dict, fallback_id: str) -> str:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fallback_id 太怪了


for task_id, task in self._tasks.items():
# 只清理当前用户的任务
if task.user_id != user_id:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

有一个方法是 get_current_user_tasks,可以复用吗?


# 只有当任务确实是运行中状态时才减少计数
# 这里再次检查状态,确保计数器准确
if old_status in [TaskStatus.PENDING, TaskStatus.RUNNING]:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

298 行已经判断过了,这里是不是不需要再判断了?

self._running_count_by_user[user_id] -= 1

cancelled = True
should_stop_polling = True
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同理:cancelled 和 should_stop_polling 这两个变量是不是也没必要了?

except Exception as e:
log("ERROR", f"[TaskManager] Error stopping poller for task {task_id}: {e}")

# ==================== History 原子操作辅助方法(委托给 HistoryHelper)====================
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

History 原子操作辅助方法存在的意义是什么呢?

# 单节点任务执行结束
data = message.get("data", {})
prompt_id = data.get("prompt_id")
node_id = data.get("node")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个 node_id 是有用的不?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

若中间节点有输出,history会返回该工作流的所有output,元数据有nodeId,表示是那个节点的输出。

Change-Id: I0be274a0057d04051217bdac25a96a94174279f9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants