From f36456fa7d15208c4bf7b3182e42bab9a6d29c69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E5=BA=86=E8=B6=85?= Date: Wed, 30 Apr 2025 18:25:23 +0800 Subject: [PATCH 1/2] fix sometime deadlock when too many messages --- ...vider_last_used_at_when_message_created.py | 43 ++++++++++++++++--- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/api/events/event_handlers/update_provider_last_used_at_when_message_created.py b/api/events/event_handlers/update_provider_last_used_at_when_message_created.py index 59412cf87c..09a0fde460 100644 --- a/api/events/event_handlers/update_provider_last_used_at_when_message_created.py +++ b/api/events/event_handlers/update_provider_last_used_at_when_message_created.py @@ -2,19 +2,50 @@ from datetime import UTC, datetime from core.app.entities.app_invoke_entities import AgentChatAppGenerateEntity, ChatAppGenerateEntity from events.message_event import message_was_created -from extensions.ext_database import db +from extensions.ext_database import Session, db from models.provider import Provider +last_used_cache = {} +last_flush_cache_time = datetime.now(UTC).replace(tzinfo=None) + + +def try_flush_cache_to_db(): + global last_flush_cache_time + if not last_used_cache: + return + now = datetime.now(UTC).replace(tzinfo=None) + if (now - last_flush_cache_time).total_seconds() < 5: + return + last_flush_cache_time = now + + with Session(db.engine) as session: + updates = [ + {"tenant_id": tenant_id, "provider_name": provider_name, "last_used": last_used} + for (tenant_id, provider_name), last_used in last_used_cache.items() + ] + session.bulk_update_mappings(Provider, updates) + session.commit() + + last_used_cache.clear() + @message_was_created.connect def handle(sender, **kwargs): + message = sender application_generate_entity = kwargs.get("application_generate_entity") if not isinstance(application_generate_entity, ChatAppGenerateEntity | AgentChatAppGenerateEntity): return - db.session.query(Provider).filter( - Provider.tenant_id == application_generate_entity.app_config.tenant_id, - Provider.provider_name == application_generate_entity.model_conf.provider, - ).update({"last_used": datetime.now(UTC).replace(tzinfo=None)}) - db.session.commit() + tenant_id = application_generate_entity.app_config.tenant_id + provider_name = application_generate_entity.model_conf.provider + current_time = datetime.now(UTC).replace(tzinfo=None) + + if (tenant_id, provider_name) in last_used_cache: + last_used_cache[(tenant_id, provider_name)] = max( + last_used_cache[(tenant_id, provider_name)], current_time + ) + else: + last_used_cache[(tenant_id, provider_name)] = current_time + + try_flush_cache_to_db() From 33ae4d08d2488fd3e69a4ea701ce26de32ec5daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E5=BA=86=E8=B6=85?= Date: Wed, 30 Apr 2025 18:35:22 +0800 Subject: [PATCH 2/2] package --- .../update_provider_last_used_at_when_message_created.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/api/events/event_handlers/update_provider_last_used_at_when_message_created.py b/api/events/event_handlers/update_provider_last_used_at_when_message_created.py index 09a0fde460..147943c46d 100644 --- a/api/events/event_handlers/update_provider_last_used_at_when_message_created.py +++ b/api/events/event_handlers/update_provider_last_used_at_when_message_created.py @@ -1,8 +1,10 @@ from datetime import UTC, datetime +from sqlalchemy.orm import Session + from core.app.entities.app_invoke_entities import AgentChatAppGenerateEntity, ChatAppGenerateEntity from events.message_event import message_was_created -from extensions.ext_database import Session, db +from extensions.ext_database import db from models.provider import Provider last_used_cache = {} @@ -31,7 +33,6 @@ def try_flush_cache_to_db(): @message_was_created.connect def handle(sender, **kwargs): - message = sender application_generate_entity = kwargs.get("application_generate_entity") if not isinstance(application_generate_entity, ChatAppGenerateEntity | AgentChatAppGenerateEntity):