[perf] Extension list cache (#3616)
This commit is contained in:
parent
ca94909aab
commit
ad268516a9
4 changed files with 45 additions and 2 deletions
|
|
@ -6,6 +6,7 @@ import json
|
|||
import os
|
||||
import shutil
|
||||
import zipfile
|
||||
from asyncio.tasks import create_task
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
|
@ -20,6 +21,7 @@ from lnbits.helpers import (
|
|||
version_parse,
|
||||
)
|
||||
from lnbits.settings import settings
|
||||
from lnbits.utils.cache import cache
|
||||
|
||||
|
||||
class ExplicitRelease(BaseModel):
|
||||
|
|
@ -606,6 +608,37 @@ class InstallableExtension(BaseModel):
|
|||
|
||||
@classmethod
|
||||
async def get_installable_extensions(
|
||||
cls, post_refresh_cache: bool = False
|
||||
) -> list[InstallableExtension]:
|
||||
extension_list: list[InstallableExtension] = []
|
||||
|
||||
cache_key = "extensions:installable"
|
||||
cache_value = cache.value(cache_key)
|
||||
if not cache_value:
|
||||
extension_list = await cls._get_installable_extensions()
|
||||
cache.set(cache_key, extension_list, expiry=3600) # one hour
|
||||
return extension_list
|
||||
|
||||
if cache_value.older_than(10 * 60) or post_refresh_cache:
|
||||
# refresh cache in background if older than 10 minutes or requested
|
||||
create_task(cls._refresh_installable_extensions_cache())
|
||||
|
||||
extension_list = cache_value.value # type: ignore
|
||||
return extension_list
|
||||
|
||||
@classmethod
|
||||
async def _refresh_installable_extensions_cache(
|
||||
cls,
|
||||
) -> None:
|
||||
cache_key = "extensions:installable"
|
||||
extension_list: list[InstallableExtension] = (
|
||||
await cls._get_installable_extensions()
|
||||
)
|
||||
|
||||
cache.set(cache_key, extension_list, expiry=3600)
|
||||
|
||||
@classmethod
|
||||
async def _get_installable_extensions(
|
||||
cls,
|
||||
) -> list[InstallableExtension]:
|
||||
extension_list: list[InstallableExtension] = []
|
||||
|
|
|
|||
|
|
@ -57,7 +57,9 @@ async def run_by_the_minute_tasks() -> None:
|
|||
if minute_counter % 60 == 0:
|
||||
try:
|
||||
# initialize the list of all extensions
|
||||
await InstallableExtension.get_installable_extensions()
|
||||
await InstallableExtension.get_installable_extensions(
|
||||
post_refresh_cache=True
|
||||
)
|
||||
except Exception as ex:
|
||||
logger.error(ex)
|
||||
|
||||
|
|
|
|||
|
|
@ -508,7 +508,9 @@ async def extensions(account_id: AccountId = Depends(check_account_id_exists)):
|
|||
installed_exts: list[InstallableExtension] = await get_installed_extensions()
|
||||
installed_exts_ids = [e.id for e in installed_exts]
|
||||
|
||||
installable_exts = await InstallableExtension.get_installable_extensions()
|
||||
installable_exts = await InstallableExtension.get_installable_extensions(
|
||||
post_refresh_cache=account_id.is_admin_id
|
||||
)
|
||||
installable_exts_ids = [e.id for e in installable_exts]
|
||||
installable_exts += [e for e in installed_exts if e.id not in installable_exts_ids]
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ class Cached(NamedTuple):
|
|||
value: Any
|
||||
expiry: float
|
||||
|
||||
def older_than(self, seconds: float) -> bool:
|
||||
return time() - self.expiry > seconds
|
||||
|
||||
|
||||
class Cache:
|
||||
"""
|
||||
|
|
@ -23,6 +26,9 @@ class Cache:
|
|||
self.interval = interval
|
||||
self._values: dict[Any, Cached] = {}
|
||||
|
||||
def value(self, key: str) -> Cached | None:
|
||||
return self._values.get(key)
|
||||
|
||||
def get(self, key: str, default=None) -> Any | None:
|
||||
cached = self._values.get(key)
|
||||
if cached is not None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue