Improve caching method: using sched.scheduler

This commit is contained in:
Jules 2020-11-01 21:57:49 +01:00
parent b93a5ae814
commit dff7b57c79
2 changed files with 37 additions and 20 deletions

View file

@ -1,6 +1,6 @@
from flask import Flask, make_response from flask import Flask, make_response
from app.tools.caching import * from app.tools.caching import CacheThread
from app.tools.tools import * from app.tools.tools import *
app = Flask(__name__) app = Flask(__name__)
@ -22,8 +22,7 @@ def main(calendar):
return response return response
# TODO find better way to launch periodic caching
# Maybe try with https://docs.python.org/3/library/sched.html
thread = CacheThread() thread = CacheThread()
thread.start() thread.start()
app.run(host='0.0.0.0', port=8088) app.run(host='0.0.0.0', port=8088)

View file

@ -1,5 +1,6 @@
import json import json
import os import os
import sched
import threading import threading
import time import time
from hashlib import sha256 from hashlib import sha256
@ -9,16 +10,21 @@ import requests
from ics import Calendar from ics import Calendar
def cache(entry: dict) -> None: def cache(entry: dict, scheduler: sched.scheduler = None) -> None:
"""Cache an .ics feed in the app/cache directory. """Cache an .ics feed in the app/cache directory.
Different entries with the same URL will be cached in the same file. Different entries with the same URL will be cached in the same file.
The cached calendar contains a new line in the description with the current time when cached prefixed by the The cached calendar contains a new line in the description with the current time when cached prefixed by the
'Cached at' mention 'Cached at' mention
:param entry: representation of the entry to cache. This is the Python representation of the corresponding entry :param entry: representation of the entry to cache. This is the Python representation of the corresponding entry
in the config file in the config file
:type entry: dict :type entry: dict
:param scheduler: scheduler used to relaunch the caching task in the future. If not scheduler is specified,
the task will not be relaunched
:type scheduler: sched.scheduler
""" """
if not os.path.isdir('app/cache'): if not os.path.isdir('app/cache'):
@ -27,14 +33,25 @@ def cache(entry: dict) -> None:
url = entry['url'] url = entry['url']
path = "app/cache/" + sha256(url.encode()).hexdigest() + ".ics" path = "app/cache/" + sha256(url.encode()).hexdigest() + ".ics"
r = requests.get(entry["url"], allow_redirects=True) try:
if "encoding" in entry: r = requests.get(entry["url"], allow_redirects=True)
cal = Calendar(imports=r.content.decode(encoding=entry["encoding"])) except Exception as e:
print(arrow.now().format("YYYY-MM-DD HH:mm:ss"), "Could not cache", entry)
print(e)
else: else:
cal = Calendar(imports=r.content.decode()) if "encoding" in entry:
cal = Calendar(imports=r.content.decode(encoding=entry["encoding"]))
else:
cal = Calendar(imports=r.content.decode())
cal = horodate(cal, 'Cached at') cal = horodate(cal, 'Cached at')
open(path, 'w').writelines(cal) open(path, 'w').writelines(cal)
print(arrow.now().format("YYYY-MM-DD HH:mm:ss"), "Cached", entry['name'])
finally:
if scheduler is not None:
delay = entry['cache'] if entry['cache'] > 0 else 10
delay *= 60
scheduler.enter(delay=delay, priority=1, action=cache, argument=(entry, scheduler))
def get_from_cache(entry: dict) -> Calendar: def get_from_cache(entry: dict) -> Calendar:
@ -122,8 +139,12 @@ def horodate(cal: Calendar, prefix='') -> Calendar:
return cal return cal
def background_cache() -> None: def start_scheduler(scheduler: sched.scheduler) -> None:
"""Start the caching of every config file found in the app/config directory """Start the caching of every config file found in the app/config directory
:param scheduler: scheduler object to use to schedule the caching
:type scheduler: sched.scheduler
""" """
path = "app/config" path = "app/config"
@ -135,22 +156,19 @@ def background_cache() -> None:
config = json.loads(config_file.read()) config = json.loads(config_file.read())
for entry in config: for entry in config:
if 'cache' in entry and entry['cache']: if 'cache' in entry:
try: scheduler.enter(delay=0, priority=1, action=cache, argument=(entry, scheduler))
cache(entry)
except: scheduler.run()
print("Could not cache", entry)
print('Cache renewed', arrow.now().format("YYYY-MM-DD HH:mm:ss"))
class CacheThread(threading.Thread): class CacheThread(threading.Thread):
"""Child class of the threading.Thread class to run the caching process every 10 minutes """Child class of the threading.Thread class to run the caching process every 10 minutes
""" """
def __init__(self): def __init__(self):
threading.Thread.__init__(self) threading.Thread.__init__(self)
def run(self): def run(self):
print("Starting cache process") print("Starting cache process")
while True: start_scheduler(sched.scheduler(time.time, time.sleep))
background_cache()
time.sleep(10 * 60)