From c426c23567f62a74a9d65944c8c449afc7ed0e3e Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Wed, 24 Jun 2026 08:59:55 +0300 Subject: [PATCH] perf: cache wasm component --- lnbits/core/extensions/loader.py | 3 +++ lnbits/core/extensions/wasm.py | 26 +++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/lnbits/core/extensions/loader.py b/lnbits/core/extensions/loader.py index 4a825d973..bbff64e97 100644 --- a/lnbits/core/extensions/loader.py +++ b/lnbits/core/extensions/loader.py @@ -44,6 +44,9 @@ def load_wasm_extension_config(ext_id: str) -> dict[str, Any] | None: def register_wasm_extension(app: FastAPI, ext_id: str) -> WasmExtension: loaded = load_wasm_extension(ext_id) + from .wasm import warm_wasm_extension + + warm_wasm_extension(loaded) _mount_wasm_extension_static(app, loaded) _register_wasm_extension_routes(app, loaded) _register_wasm_extension_api_routes(app, loaded) diff --git a/lnbits/core/extensions/wasm.py b/lnbits/core/extensions/wasm.py index a2d28439c..0dd8ad688 100644 --- a/lnbits/core/extensions/wasm.py +++ b/lnbits/core/extensions/wasm.py @@ -35,6 +35,10 @@ async def invoke_wasm_extension_export( ) +def warm_wasm_extension(extension: WasmExtension) -> None: + _wasm_component(extension) + + def _invoke_wasm_extension_export_sync( extension: WasmExtension, export_name: str, @@ -57,7 +61,7 @@ def _invoke_wasm_extension_export_sync( linker.add_wasip2() _add_extension_host_imports(linker, ExtensionAPIHost(api)) - wasm_component = component.Component.from_file(engine, extension.module_path) + wasm_component = _wasm_component(extension) instance = linker.instantiate(store, wasm_component) function = instance.get_func(store, export_name) if not function: @@ -83,6 +87,26 @@ def _wasm_engine() -> Any: return Engine(config) +def _wasm_component(extension: WasmExtension) -> Any: + stat = extension.module_path.stat() + return _cached_wasm_component( + str(extension.module_path), + stat.st_mtime_ns, + stat.st_size, + ) + + +@lru_cache(maxsize=32) +def _cached_wasm_component( + module_path: str, + mtime_ns: int, + size: int, +) -> Any: + from wasmtime import component + + return component.Component.from_file(_wasm_engine(), module_path) + + def _add_extension_host_imports(linker: Any, api_host: ExtensionAPIHost) -> None: with linker.root() as root: with root.add_instance("lnbits:extension/host") as host: