perf(channels): batch user lookup in model_response_handler thread history (#23795)

* perf(channels): batch user lookup in model_response_handler thread history

The thread-history builder in model_response_handler called
Users.get_user_by_id once per thread message (deduped via an intra-loop
dict), producing N individual SELECTs for a thread of N unique authors.

Replace with a single Users.get_users_by_user_ids call that returns all
authors in one WHERE id IN (...) query, matching the batch pattern
already used elsewhere in this file (lines 739, 804, 1320).

Behavior is preserved: deleted users still resolve to None and fall
through to the existing 'Unknown' fallback via .get().

* refac(channels): rename loop vars to full words per review

Address reviewer feedback to use descriptive names `message` and `user`
instead of single-letter `m` and `u` in the batch user-lookup
comprehensions.

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Classic298
2026-04-20 08:37:07 +09:00
committed by GitHub
co-authored by Claude
parent 56c5bc1d34
commit b3ca943da1
+5 -7
View File
@@ -923,15 +923,13 @@ async def model_response_handler(request, channel, message, user, db=None):
thread_history = []
images = []
message_users = {}
# Batch fetch all users in a single query (fixes N+1 problem)
user_ids = list({message.user_id for message in thread_messages})
message_users = {user.id: user for user in await Users.get_users_by_user_ids(user_ids, db=db)}
for thread_message in thread_messages:
message_user = None
if thread_message.user_id not in message_users:
message_user = await Users.get_user_by_id(thread_message.user_id, db=db)
message_users[thread_message.user_id] = message_user
else:
message_user = message_users[thread_message.user_id]
message_user = message_users.get(thread_message.user_id)
if thread_message.meta and thread_message.meta.get('model_id', None):
# If the message was sent by a model, use the model name