Improve caching method: using sched.scheduler
This commit is contained in:
parent
b93a5ae814
commit
dff7b57c79
2 changed files with 37 additions and 20 deletions
|
@ -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)
|
||||||
|
|
|
@ -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)
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue