Skip to content

Commit 3e52b39

Browse files
Algorithm5838github-actions[bot]
authored andcommitted
perf: collapse chat write helpers into single db session
1 parent c82646c commit 3e52b39

1 file changed

Lines changed: 69 additions & 42 deletions

File tree

backend/open_webui/models/chats.py

Lines changed: 69 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import json
33
import time
44
import uuid
5-
from typing import Optional
5+
from typing import Optional, Callable
66

77
from sqlalchemy.orm import Session
88
from open_webui.internal.db import Base, JSONField, get_db, get_db_context
@@ -462,62 +462,89 @@ def get_message_by_id_and_message_id(self, id: str, message_id: str) -> Optional
462462
return chat.chat.get('history', {}).get('messages', {}).get(message_id, {})
463463

464464
def upsert_message_to_chat_by_id_and_message_id(
465-
self, id: str, message_id: str, message: dict
465+
self,
466+
id: str,
467+
message_id: str,
468+
message: dict,
469+
merge_fn: Optional[Callable[[dict], dict]] = None,
466470
) -> Optional[ChatModel]:
467-
chat = self.get_chat_by_id(id)
468-
if chat is None:
469-
return None
471+
try:
472+
with get_db_context() as db:
473+
chat_item = db.get(Chat, id)
474+
if chat_item is None:
475+
return None
470476

471-
# Sanitize message content for null characters before upserting
472-
if isinstance(message.get('content'), str):
473-
message['content'] = sanitize_text_for_db(message['content'])
477+
user_id = chat_item.user_id
478+
chat = chat_item.chat
479+
history = chat.get('history', {})
474480

475-
user_id = chat.user_id
476-
chat = chat.chat
477-
history = chat.get('history', {})
481+
if merge_fn is not None:
482+
existing_message = history.get('messages', {}).get(message_id, {})
483+
message = merge_fn(existing_message)
478484

479-
if message_id in history.get('messages', {}):
480-
history['messages'][message_id] = {
481-
**history['messages'][message_id],
482-
**message,
483-
}
484-
else:
485-
history['messages'][message_id] = message
485+
# Sanitize message content for null characters before upserting
486+
if isinstance(message.get('content'), str):
487+
message['content'] = sanitize_text_for_db(message['content'])
486488

487-
history['currentId'] = message_id
489+
if message_id in history.get('messages', {}):
490+
history['messages'][message_id] = {
491+
**history['messages'][message_id],
492+
**message,
493+
}
494+
else:
495+
history['messages'][message_id] = message
488496

489-
chat['history'] = history
497+
history['currentId'] = message_id
498+
chat['history'] = history
490499

491-
# Dual-write to chat_message table
492-
try:
493-
ChatMessages.upsert_message(
494-
message_id=message_id,
495-
chat_id=id,
496-
user_id=user_id,
497-
data=history['messages'][message_id],
498-
)
499-
except Exception as e:
500-
log.warning(f'Failed to write to chat_message table: {e}')
500+
chat_item.chat = self._clean_null_bytes(chat)
501+
chat_item.title = self._clean_null_bytes(chat['title']) if 'title' in chat else 'New Chat'
502+
chat_item.updated_at = int(time.time())
503+
db.commit()
504+
db.refresh(chat_item)
505+
506+
# Dual-write to chat_message table
507+
try:
508+
ChatMessages.upsert_message(
509+
message_id=message_id,
510+
chat_id=id,
511+
user_id=user_id,
512+
data=history['messages'][message_id],
513+
)
514+
except Exception as e:
515+
log.warning(f'Failed to write to chat_message table: {e}')
501516

502-
return self.update_chat_by_id(id, chat)
517+
return ChatModel.model_validate(chat_item)
518+
except Exception:
519+
return None
503520

504521
def add_message_status_to_chat_by_id_and_message_id(
505522
self, id: str, message_id: str, status: dict
506523
) -> Optional[ChatModel]:
507-
chat = self.get_chat_by_id(id)
508-
if chat is None:
509-
return None
524+
try:
525+
with get_db_context() as db:
526+
chat_item = db.get(Chat, id)
527+
if chat_item is None:
528+
return None
529+
530+
chat = chat_item.chat
531+
history = chat.get('history', {})
510532

511-
chat = chat.chat
512-
history = chat.get('history', {})
533+
if message_id in history.get('messages', {}):
534+
status_history = history['messages'][message_id].get('statusHistory', [])
535+
status_history.append(status)
536+
history['messages'][message_id]['statusHistory'] = status_history
513537

514-
if message_id in history.get('messages', {}):
515-
status_history = history['messages'][message_id].get('statusHistory', [])
516-
status_history.append(status)
517-
history['messages'][message_id]['statusHistory'] = status_history
538+
chat['history'] = history
518539

519-
chat['history'] = history
520-
return self.update_chat_by_id(id, chat)
540+
chat_item.chat = self._clean_null_bytes(chat)
541+
chat_item.updated_at = int(time.time())
542+
db.commit()
543+
db.refresh(chat_item)
544+
545+
return ChatModel.model_validate(chat_item)
546+
except Exception:
547+
return None
521548

522549
def add_message_files_by_id_and_message_id(self, id: str, message_id: str, files: list[dict]) -> list[dict]:
523550
with get_db_context() as db:

0 commit comments

Comments
 (0)