Pārlūkot izejas kodu

fix loading stale files and race condition

Daniel Sheffield 1 gadu atpakaļ
vecāks
revīzija
a59db9dd95
2 mainītis faili ar 24 papildinājumiem un 5 dzēšanām
  1. 21 4
      app/rest/Cache.py
  2. 3 1
      app/rest/CachedLoadingPage.py

+ 21 - 4
app/rest/Cache.py

@@ -4,10 +4,11 @@
 #
 # THIS SOFTWARE IS PROVIDED AS IS WITHOUT WARRANTY
 import os
+import time
 from typing import Dict
 
 from .hash_util import blake, bytes_to_hash, hash_to_base32
-from .CachedLoadingPage import CachedLoadingPage
+from .CachedLoadingPage import STALE, CachedLoadingPage
 
 def delete_page(name: str, root: str = 'app/rest/static/files'):
     directory = f'{root}/{name}'
@@ -16,6 +17,11 @@ def delete_page(name: str, root: str = 'app/rest/static/files'):
     except FileNotFoundError:
         pass
 
+    try:
+        os.rmdir(directory)
+    except FileNotFoundError:
+        pass
+
 def save_page(name: str, content: bytes, tool: str, root='app/rest/static/files') -> str:
     directory = f'{root}/{name}'
     try:
@@ -30,7 +36,14 @@ def save_page(name: str, content: bytes, tool: str, root='app/rest/static/files'
 def get_page(name: str, root: str = 'app/rest/static/files') -> str:
     directory = f'{root}/{name}'
 
-    # todo: if page is stale, delete it
+    try:
+        mtime = os.stat(f'{directory}/{name}.file').st_mtime
+    except:
+        mtime = None
+    
+    if mtime and time.now() - mtime > STALE:
+        delete_page(name)
+        return None
 
     # todo: store file hash and validate it
     fd = os.open(f'{directory}/{name}.file', os.O_RDONLY, 0o600)
@@ -103,8 +116,12 @@ class Cache:
             if not page.loaded:
                 return page
 
-            content = ''.join(page.value) if isinstance(page.value, list) else page.value
-            save_page(hash_to_base32(key), content.encode('utf-8'), tool='grocery')
+        if page.loaded:
+            try:
+                existing = get_page(hash_to_base32(key))
+            except:
+                content = ''.join(page.value) if isinstance(page.value, list) else page.value
+                save_page(hash_to_base32(key), content.encode('utf-8'), tool='grocery')
 
         return page
 

+ 3 - 1
app/rest/CachedLoadingPage.py

@@ -8,6 +8,8 @@ from time import time
 from threading import Lock
 from typing import Callable, Union
 
+STALE = 10*60
+
 class CachedLoadingPage():
     
     value: str
@@ -39,7 +41,7 @@ class CachedLoadingPage():
     
     @property
     def stale(self) -> bool:
-        return self.age > 10*60
+        return self.age > STALE
     
     def _start(self) -> None:
         if not self.provider: