|
@@ -17,7 +17,7 @@ from bottle import (
|
|
|
)
|
|
|
from psycopg import connect
|
|
|
from psycopg.sql import SQL, Literal
|
|
|
-from threading import Lock, Thread
|
|
|
+from threading import Thread
|
|
|
|
|
|
from ..data.filter import(
|
|
|
get_filter,
|
|
@@ -30,6 +30,7 @@ from ..data.util import(
|
|
|
from . import trend as worker
|
|
|
from . import PARAMS
|
|
|
from .CachedLoadingPage import CachedLoadingPage
|
|
|
+from .Cache import Cache
|
|
|
|
|
|
host = f"host={os.getenv('HOST')}"
|
|
|
db = f"dbname={os.getenv('DB', 'grocery')}"
|
|
@@ -39,19 +40,7 @@ if not password.split('=',1)[1]:
|
|
|
password = ''
|
|
|
conn = connect(f"{host} {db} {user} {password}")
|
|
|
|
|
|
-CACHE: Dict[str, CachedLoadingPage] = dict()
|
|
|
-
|
|
|
-def enforce_limit(cache, limit):
|
|
|
- for idx, (_, k) in enumerate(sorted([
|
|
|
- (v.age, k) for k, v in cache.items()
|
|
|
- ])):
|
|
|
- if idx > limit: del cache[k]
|
|
|
-
|
|
|
-
|
|
|
-def clear_stale(cache):
|
|
|
- for k in [k for k, v in cache.items() if v.stale]:
|
|
|
- del cache[k]
|
|
|
-
|
|
|
+CACHE = Cache(10)
|
|
|
|
|
|
def get_product_rollup_statement(filters, having=None):
|
|
|
where = [ get_where_include_exclude(
|
|
@@ -94,36 +83,24 @@ def normalize_query(query: FormsDict, allow: Iterable[str] = None) -> str:
|
|
|
def send_static(filename):
|
|
|
return static_file(filename, root='app/rest/static')
|
|
|
|
|
|
-global LOCK
|
|
|
-LOCK = Lock()
|
|
|
-
|
|
|
@route('/grocery/trend')
|
|
|
def trend():
|
|
|
_, _, path, *_ = request.urlparts
|
|
|
normalized = normalize_query(request.query, allow=PARAMS)
|
|
|
- if normalized in CACHE:
|
|
|
- if request.params.get('reload') == 'true':
|
|
|
- del CACHE[normalized]
|
|
|
+ if request.params.get('reload') == 'true':
|
|
|
+ CACHE.remove(normalized)
|
|
|
|
|
|
if request.query_string != normalized:
|
|
|
return redirect(f'{path}?{normalized}')
|
|
|
|
|
|
- if request.query_string in CACHE:
|
|
|
- page = CACHE[request.query_string]
|
|
|
- if not page.stale:
|
|
|
- return page.value if page.loaded else page.update()
|
|
|
- del CACHE[request.query_string]
|
|
|
+ page = CACHE.get(normalized)
|
|
|
|
|
|
- page = CachedLoadingPage(
|
|
|
+ return page if page else CACHE.add(normalized, CachedLoadingPage(
|
|
|
template("loading", progress=[]),
|
|
|
lambda queue: Thread(target=worker.trend, args=(
|
|
|
queue, conn, path, request.query
|
|
|
)).start()
|
|
|
- )
|
|
|
- clear_stale(CACHE)
|
|
|
- enforce_limit(CACHE, 10)
|
|
|
- CACHE[request.query_string] = page
|
|
|
- return page.value
|
|
|
+ ))
|
|
|
|
|
|
@route('/grocery/groups')
|
|
|
def groups():
|