mirror of
https://github.com/langgenius/dify.git
synced 2026-09-08 11:04:27 +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
|
@property
|
||||||
def participants(self):
|
def participants(self):
|
||||||
"""Get all participants (creator + repliers + mentioned users)."""
|
"""Get all participants (creator + repliers + mentioned users)."""
|
||||||
participant_ids = set()
|
participant_ids: set[str] = set()
|
||||||
|
participants: list[Account] = []
|
||||||
|
|
||||||
# Add comment creator
|
# Use account properties to reuse preloaded caches and avoid hidden N+1.
|
||||||
participant_ids.add(self.created_by)
|
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
|
for reply in self.replies:
|
||||||
participant_ids.update(reply.created_by 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
|
for mention in self.mentions:
|
||||||
participant_ids.update(mention.mentioned_user_id for mention in self.mentions)
|
if mention.mentioned_user_id in participant_ids:
|
||||||
|
continue
|
||||||
# Get account objects
|
participant_ids.add(mention.mentioned_user_id)
|
||||||
participants = []
|
mentioned_account = mention.mentioned_user_account
|
||||||
for user_id in participant_ids:
|
if mentioned_account:
|
||||||
account = db.session.get(Account, user_id)
|
participants.append(mentioned_account)
|
||||||
if account:
|
|
||||||
participants.append(account)
|
|
||||||
|
|
||||||
return participants
|
return participants
|
||||||
|
|
||||||
|
|||||||
@ -60,6 +60,27 @@ def test_workflow_comment_counts_and_participants() -> None:
|
|||||||
assert get_mock.call_count == 4
|
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:
|
def test_reply_and_mention_account_properties_and_cache() -> None:
|
||||||
reply = WorkflowCommentReply(comment_id="comment-1", content="reply", created_by="user-1")
|
reply = WorkflowCommentReply(comment_id="comment-1", content="reply", created_by="user-1")
|
||||||
mention = WorkflowCommentMention(comment_id="comment-1", mentioned_user_id="user-2")
|
mention = WorkflowCommentMention(comment_id="comment-1", mentioned_user_id="user-2")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user