mirror of
https://github.com/langgenius/dify.git
synced 2026-08-29 03:45:08 +08:00
perf(api): batch recommended app catalog lookups (#41218)
This commit is contained in:
@@ -10,7 +10,7 @@ from sqlalchemy.orm import Session, sessionmaker
|
||||
|
||||
from constants.languages import languages
|
||||
from extensions.ext_redis import RedisClientWrapper
|
||||
from models.model import App, RecommendedApp
|
||||
from models.model import App, RecommendedApp, Site
|
||||
from services.app_dsl_service import AppDslService
|
||||
from services.recommended_app_query_service import (
|
||||
RecommendedAppCatalogPage,
|
||||
@@ -117,14 +117,23 @@ class DatabaseRecommendedAppCatalogRepository(RecommendedAppCatalogQuery):
|
||||
*,
|
||||
session: Session,
|
||||
) -> tuple[tuple[RecommendedAppRecord, ...], set[str]]:
|
||||
if not recommended_apps:
|
||||
return (), set()
|
||||
|
||||
app_ids = [recommended_app.app_id for recommended_app in recommended_apps]
|
||||
apps_by_id = {app.id: app for app in session.scalars(select(App).where(App.id.in_(app_ids))).all()}
|
||||
sites_by_app_id = {
|
||||
site.app_id: site for site in session.scalars(select(Site).where(Site.app_id.in_(app_ids))).all()
|
||||
}
|
||||
|
||||
categories: set[str] = set()
|
||||
records: list[RecommendedAppRecord] = []
|
||||
for recommended_app in recommended_apps:
|
||||
app = session.get(App, recommended_app.app_id)
|
||||
app = apps_by_id.get(recommended_app.app_id)
|
||||
if app is None or not app.is_public:
|
||||
continue
|
||||
|
||||
site = app.site_with_session(session=session)
|
||||
site = sites_by_app_id.get(app.id)
|
||||
if site is None:
|
||||
continue
|
||||
|
||||
|
||||
@@ -103,6 +103,30 @@ def test_list_recommended_returns_typed_records_and_falls_back_language(
|
||||
assert record.categories == ("Workflow",)
|
||||
|
||||
|
||||
def test_list_recommended_batches_app_and_site_lookups(
|
||||
sqlite_engine: Engine,
|
||||
sqlite_session_factory: sessionmaker[Session],
|
||||
) -> None:
|
||||
with sqlite_session_factory() as session:
|
||||
app_ids = {_add_catalog_app(session).id for _ in range(3)}
|
||||
|
||||
select_count = 0
|
||||
|
||||
def count_selects(_conn, _cursor, statement: str, _parameters, _context, _executemany) -> None:
|
||||
nonlocal select_count
|
||||
if statement.lstrip().upper().startswith("SELECT"):
|
||||
select_count += 1
|
||||
|
||||
event.listen(sqlite_engine, "before_cursor_execute", count_selects)
|
||||
try:
|
||||
page = _repository(sqlite_session_factory).list_recommended("en-US")
|
||||
finally:
|
||||
event.remove(sqlite_engine, "before_cursor_execute", count_selects)
|
||||
|
||||
assert {app.app_id for app in page.recommended_apps} == app_ids
|
||||
assert select_count == 3
|
||||
|
||||
|
||||
def test_list_recommended_skips_private_apps_and_apps_without_sites(
|
||||
sqlite_session_factory: sessionmaker[Session],
|
||||
) -> None:
|
||||
|
||||
Reference in New Issue
Block a user