[CHORE] cleanup cache and exception on make test (#1899)

* [CHORE] cleanup cache and exception on `make test`

moved the invalidate_forever task to proper location and use `create_permanent_task`.
and there was a Task never awaited Exception when running tests

* imrpove expiration test

* move cache into utils

* fix issue with pytest_asyncio

s

---------

Co-authored-by: jacksn <jkranawetter05@gmail.com>
This commit is contained in:
dni ⚡ 2023-08-28 11:56:59 +02:00 committed by GitHub
parent 6077edad8f
commit 48f25488df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 18 deletions

View file

@ -20,7 +20,6 @@ from slowapi import Limiter
from slowapi.util import get_remote_address
from starlette.responses import JSONResponse
from lnbits.cache import cache
from lnbits.core.crud import get_installed_extensions
from lnbits.core.helpers import migrate_extension_database
from lnbits.core.services import websocketUpdater
@ -30,6 +29,7 @@ from lnbits.core.tasks import ( # register_watchdog,; unregister_watchdog,
)
from lnbits.settings import settings
from lnbits.tasks import cancel_all_tasks, create_permanent_task
from lnbits.utils.cache import cache
from lnbits.wallets import get_wallet_class, set_wallet_class
from .commands import db_versions, load_disabled_extension_list, migrate_databases
@ -358,8 +358,6 @@ def register_startup(app: FastAPI):
if settings.lnbits_admin_ui:
initialize_server_logger()
asyncio.create_task(cache.invalidate_forever())
except Exception as e:
logger.error(str(e))
raise ImportError("Failed to run 'startup' event.")
@ -431,6 +429,7 @@ def register_async_tasks(app):
create_permanent_task(check_pending_payments)
create_permanent_task(invoice_listener)
create_permanent_task(internal_invoice_listener)
create_permanent_task(cache.invalidate_forever)
register_task_listeners()
register_killswitch()
# await run_deferred_async() # calle: doesn't do anyting?

View file

@ -17,7 +17,8 @@ class Cache:
Small caching utility providing simple get/set interface (very much like redis)
"""
def __init__(self) -> None:
def __init__(self, interval: float = 10) -> None:
self.interval = interval
self._values: dict[Any, Cached] = {}
def get(self, key: str, default=None) -> Optional[Any]:
@ -50,10 +51,10 @@ class Cache:
self.set(key, value, expiry=expiry)
return value
async def invalidate_forever(self, interval: float = 10):
async def invalidate_forever(self):
while True:
try:
await asyncio.sleep(interval)
await asyncio.sleep(self.interval)
ts = time()
expired = [k for k, v in self._values.items() if v.expiry < ts]
for k in expired:

View file

@ -4,7 +4,7 @@ from typing import Callable, NamedTuple
import httpx
from loguru import logger
from lnbits.cache import cache
from lnbits.utils.cache import cache
currencies = {
"AED": "United Arab Emirates Dirham",

View file

@ -2,23 +2,22 @@ import asyncio
import pytest
from lnbits.cache import Cache
from lnbits.utils.cache import Cache
from tests.conftest import pytest_asyncio
@pytest_asyncio.fixture(scope="session")
async def cache():
cache = Cache()
task = asyncio.create_task(cache.invalidate_forever(interval=0.1))
yield cache
task.cancel()
key = "foo"
value = "bar"
@pytest_asyncio.fixture
async def cache():
cache = Cache(interval=0.1)
task = asyncio.create_task(cache.invalidate_forever())
yield cache
task.cancel()
@pytest.mark.asyncio
async def test_cache_get_set(cache):
cache.set(key, value)
@ -29,8 +28,15 @@ async def test_cache_get_set(cache):
@pytest.mark.asyncio
async def test_cache_expiry(cache):
# gets expired by `get` call
cache.set(key, value, expiry=0.01)
await asyncio.sleep(0.02)
assert not cache.get(key)
# gets expired by invalidation task
cache.set(key, value, expiry=0.1)
await asyncio.sleep(0.2)
assert key not in cache._values
assert not cache.get(key)