44 lines
1.4 KiB
Python
44 lines
1.4 KiB
Python
|
from functools import lru_cache
|
||
|
|
||
|
import requests
|
||
|
|
||
|
from reflex_cache.util import Uncached
|
||
|
|
||
|
|
||
|
class NixCacheFetcher:
|
||
|
def __init__(self, caches):
|
||
|
self.__caches = caches
|
||
|
|
||
|
@lru_cache(maxsize=32768)
|
||
|
def __try_all_cached(self, method, path):
|
||
|
fn = requests.get if method == "get" else requests.head if method == "head" else Error("invalid method")
|
||
|
|
||
|
bestState = 404
|
||
|
|
||
|
print(f" fetching [{method}] from any cache {path}")
|
||
|
for cache in self.__caches:
|
||
|
try:
|
||
|
rCache = fn(f"{cache}{path}")
|
||
|
if rCache.status_code < bestState:
|
||
|
bestState = rCache.status_code
|
||
|
|
||
|
print(f" {rCache.status_code} - [{method}] {cache}{path}")
|
||
|
if bestState == 200:
|
||
|
r = (bestState,rCache.content if method != "head" else False)
|
||
|
if path.endswith(".narinfo"):
|
||
|
return r
|
||
|
else:
|
||
|
raise Uncached(r)
|
||
|
except requests.ConnectionError as e:
|
||
|
print(e)
|
||
|
|
||
|
# HACK: lru_cache does not cache results if an exception occurs
|
||
|
# since we don't want to cache empty query results, we make use of this behavior
|
||
|
raise Uncached((bestState,False))
|
||
|
|
||
|
def try_all(self, method, path):
|
||
|
try:
|
||
|
return self.__try_all_cached(method, path)
|
||
|
except Uncached as r:
|
||
|
return r.args[0]
|