timed_alru_cache decorator

This commit is contained in:
Jörn-Michael Miehe 2022-09-04 17:12:01 +00:00
parent 9b969b6024
commit 2c778b0d3a
2 changed files with 28 additions and 17 deletions

View file

@ -1,8 +1,10 @@
import asyncio import asyncio
import functools import functools
import time
from typing import Any from typing import Any
import caldav import caldav
from async_lru import alru_cache
from webdav3 import client as WebDAVclient from webdav3 import client as WebDAVclient
from .config import SETTINGS from .config import SETTINGS
@ -31,6 +33,28 @@ def run_in_executor(f):
return inner return inner
def get_ttl_hash(seconds: int = 20) -> int:
"""
Return the same value within `seconds` time period
https://stackoverflow.com/a/55900800
"""
return round(time.time() / seconds)
def timed_alru_cache(**decorator_kwargs):
def decorate(f):
@alru_cache(**decorator_kwargs)
@functools.wraps(f)
async def wrapper(ttl_hash: int, *args, **kwargs):
del ttl_hash
return await f(*args, **kwargs)
return wrapper
return decorate
@functools.lru_cache @functools.lru_cache
def webdav_resource(remote_path: Any) -> WebDAVclient.Resource: def webdav_resource(remote_path: Any) -> WebDAVclient.Resource:
return _WEBDAV_CLIENT.resource(remote_path) return _WEBDAV_CLIENT.resource(remote_path)

View file

@ -1,32 +1,19 @@
import logging import logging
import time
from dataclasses import dataclass from dataclasses import dataclass
from io import BytesIO from io import BytesIO
from typing import Any, Optional from typing import Any
from async_lru import alru_cache
from webdav3.client import Resource from webdav3.client import Resource
from . import run_in_executor, webdav_resource from . import get_ttl_hash, run_in_executor, timed_alru_cache, webdav_resource
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
def _get_ttl_hash(seconds: int = 20) -> int: @timed_alru_cache(maxsize=20)
"""
Return the same value within `seconds` time period
https://stackoverflow.com/a/55900800
"""
return round(time.time() / seconds)
@alru_cache(maxsize=20)
async def _get_buffer( async def _get_buffer(
remote_path: Any, remote_path: Any,
ttl_hash: Optional[int] = None,
) -> BytesIO: ) -> BytesIO:
del ttl_hash
@run_in_executor @run_in_executor
def buffer_inner(resource: Resource) -> BytesIO: def buffer_inner(resource: Resource) -> BytesIO:
_logger.info(f"updating {resource}") _logger.info(f"updating {resource}")
@ -46,8 +33,8 @@ class DavFile:
@property @property
async def __buffer(self) -> BytesIO: async def __buffer(self) -> BytesIO:
return await _get_buffer( return await _get_buffer(
ttl_hash=get_ttl_hash(),
remote_path=self.remote_path, remote_path=self.remote_path,
ttl_hash=_get_ttl_hash(20),
) )
@property @property