mirror of
https://github.com/langgenius/dify.git
synced 2026-04-15 18:06:36 +08:00
fix: avoid hidden N+1 in workflow comment participants
This commit is contained in:
parent
cadc021bfa
commit
cf74c5c8db
@ -101,23 +101,31 @@ class WorkflowComment(Base):
|
||||
@property
|
||||
def participants(self):
|
||||
"""Get all participants (creator + repliers + mentioned users)."""
|
||||
participant_ids = set()
|
||||
participant_ids: set[str] = set()
|
||||
participants: list[Account] = []
|
||||
|
||||
# Add comment creator
|
||||
participant_ids.add(self.created_by)
|
||||
# Use account properties to reuse preloaded caches and avoid hidden N+1.
|
||||
if self.created_by not in participant_ids:
|
||||
participant_ids.add(self.created_by)
|
||||
created_by_account = self.created_by_account
|
||||
if created_by_account:
|
||||
participants.append(created_by_account)
|
||||
|
||||
# Add reply creators
|
||||
participant_ids.update(reply.created_by for reply in self.replies)
|
||||
for reply in self.replies:
|
||||
if reply.created_by in participant_ids:
|
||||
continue
|
||||
participant_ids.add(reply.created_by)
|
||||
reply_account = reply.created_by_account
|
||||
if reply_account:
|
||||
participants.append(reply_account)
|
||||
|
||||
# Add mentioned users
|
||||
participant_ids.update(mention.mentioned_user_id for mention in self.mentions)
|
||||
|
||||
# Get account objects
|
||||
participants = []
|
||||
for user_id in participant_ids:
|
||||
account = db.session.get(Account, user_id)
|
||||
if account:
|
||||
participants.append(account)
|
||||
for mention in self.mentions:
|
||||
if mention.mentioned_user_id in participant_ids:
|
||||
continue
|
||||
participant_ids.add(mention.mentioned_user_id)
|
||||
mentioned_account = mention.mentioned_user_account
|
||||
if mentioned_account:
|
||||
participants.append(mentioned_account)
|
||||
|
||||
return participants
|
||||
|
||||
|
||||
@ -60,6 +60,27 @@ def test_workflow_comment_counts_and_participants() -> None:
|
||||
assert get_mock.call_count == 4
|
||||
|
||||
|
||||
def test_workflow_comment_participants_use_cached_accounts() -> None:
|
||||
reply = WorkflowCommentReply(comment_id="comment-1", content="reply-1", created_by="user-2")
|
||||
mention = WorkflowCommentMention(comment_id="comment-1", mentioned_user_id="user-3")
|
||||
comment = WorkflowComment(created_by="user-1", resolved_by=None, content="hello", position_x=1, position_y=2)
|
||||
comment.replies = [reply]
|
||||
comment.mentions = [mention]
|
||||
|
||||
account_1 = Mock(id="user-1")
|
||||
account_2 = Mock(id="user-2")
|
||||
account_3 = Mock(id="user-3")
|
||||
comment.cache_created_by_account(account_1)
|
||||
reply.cache_created_by_account(account_2)
|
||||
mention.cache_mentioned_user_account(account_3)
|
||||
|
||||
with patch("models.comment.db.session.get") as get_mock:
|
||||
participants = comment.participants
|
||||
|
||||
assert set(participants) == {account_1, account_2, account_3}
|
||||
get_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_reply_and_mention_account_properties_and_cache() -> None:
|
||||
reply = WorkflowCommentReply(comment_id="comment-1", content="reply", created_by="user-1")
|
||||
mention = WorkflowCommentMention(comment_id="comment-1", mentioned_user_id="user-2")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user