mirror of
https://github.com/langgenius/dify.git
synced 2026-05-04 17:38:04 +08:00
refactor(sandbox): async init and draft downloads
Reduce startup latency by deferring sandbox setup and downloading draft assets directly with cached presigned URLs.
This commit is contained in:
@ -1,9 +1,11 @@
|
||||
from .app_assets_initializer import AppAssetsInitializer
|
||||
from .draft_app_assets_initializer import DraftAppAssetsInitializer
|
||||
from .base import SandboxInitializer
|
||||
from .dify_cli_initializer import DifyCliInitializer
|
||||
|
||||
__all__ = [
|
||||
"AppAssetsInitializer",
|
||||
"DraftAppAssetsInitializer",
|
||||
"DifyCliInitializer",
|
||||
"SandboxInitializer",
|
||||
]
|
||||
|
||||
@ -22,18 +22,21 @@ class AppAssetsInitializer(SandboxInitializer):
|
||||
self._app_id = app_id
|
||||
self._assets_id = assets_id
|
||||
|
||||
def initialize(self, sandbox: Sandbox) -> None:
|
||||
vm = sandbox.vm
|
||||
# load app assets
|
||||
def initialize(self, env: Sandbox) -> None:
|
||||
vm = env.vm
|
||||
# Load published app assets and unzip the artifact bundle.
|
||||
app_assets = AppAssetService.get_tenant_app_assets(self._tenant_id, self._assets_id)
|
||||
sandbox.attrs.set(AppAssetsAttrs.FILE_TREE, app_assets.asset_tree)
|
||||
env.attrs.set(AppAssetsAttrs.FILE_TREE, app_assets.asset_tree)
|
||||
|
||||
zip_key = AssetPaths.build_zip(self._tenant_id, self._app_id, self._assets_id)
|
||||
download_url = FilePresignStorage(storage.storage_runner).get_download_url(zip_key)
|
||||
|
||||
(
|
||||
pipeline(vm)
|
||||
.add(["wget", "-q", download_url, "-O", AppAssets.ZIP_PATH], error_message="Failed to download assets zip")
|
||||
.add(
|
||||
["wget", "-q", download_url, "-O", AppAssets.ZIP_PATH],
|
||||
error_message="Failed to download assets zip",
|
||||
)
|
||||
# unzip with silent error and return 1 if the zip is empty
|
||||
# FIXME(Mairuis): should use a more robust way to check if the zip is empty
|
||||
.add(
|
||||
|
||||
44
api/core/sandbox/initializer/draft_app_assets_initializer.py
Normal file
44
api/core/sandbox/initializer/draft_app_assets_initializer.py
Normal file
@ -0,0 +1,44 @@
|
||||
import logging
|
||||
|
||||
from core.app_assets.constants import AppAssetsAttrs
|
||||
from core.sandbox.entities import AppAssets
|
||||
from core.sandbox.sandbox import Sandbox
|
||||
from core.sandbox.services import AssetDownloadService
|
||||
from core.sandbox.services.asset_download_service import AssetDownloadItem
|
||||
from core.virtual_environment.__base.helpers import pipeline
|
||||
from services.app_asset_service import AppAssetService
|
||||
|
||||
from .base import SandboxInitializer
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
DRAFT_ASSETS_DOWNLOAD_TIMEOUT = 60 * 10
|
||||
|
||||
|
||||
class DraftAppAssetsInitializer(SandboxInitializer):
|
||||
def __init__(self, tenant_id: str, app_id: str, assets_id: str) -> None:
|
||||
self._tenant_id = tenant_id
|
||||
self._app_id = app_id
|
||||
self._assets_id = assets_id
|
||||
|
||||
def initialize(self, env: Sandbox) -> None:
|
||||
vm = env.vm
|
||||
# Draft assets download via presigned URLs to avoid zip build overhead.
|
||||
app_assets = AppAssetService.get_tenant_app_assets(self._tenant_id, self._assets_id)
|
||||
env.attrs.set(AppAssetsAttrs.FILE_TREE, app_assets.asset_tree)
|
||||
|
||||
items = [
|
||||
AssetDownloadItem(path=path, url=url)
|
||||
for path, url in AppAssetService.get_cached_draft_download_urls(app_assets)
|
||||
]
|
||||
script = AssetDownloadService.build_download_script(items, AppAssets.PATH)
|
||||
pipeline(vm).add(
|
||||
["sh", "-lc", script],
|
||||
error_message="Failed to download draft assets",
|
||||
).execute(timeout=DRAFT_ASSETS_DOWNLOAD_TIMEOUT, raise_on_error=True)
|
||||
|
||||
logger.info(
|
||||
"Draft app assets initialized for app_id=%s, assets_id=%s",
|
||||
self._app_id,
|
||||
self._assets_id,
|
||||
)
|
||||
Reference in New Issue
Block a user