Tune performance

- Added threading to gunicorn instance
- Changed cache to cachetools's TTL cache since it uses LRU if
the cache is full
- Increased cache sizes 1.5x
This commit is contained in:
Laszlo Zeke 2020-09-04 22:36:19 +02:00
parent 5fccffc2f0
commit e303af090d
4 changed files with 18 additions and 21 deletions

2
.gitignore vendored
View File

@ -100,3 +100,5 @@ $RECYCLE.BIN/
# Windows shortcuts
*.lnk
*.gcloudignore

View File

@ -1,6 +1,6 @@
runtime: python38
entrypoint: gunicorn -b :$PORT twitchrss:app
entrypoint: gunicorn -b :$PORT -k gthread --threads 2 twitchrss:app
env_variables:
TWITCH_CLIENT_ID: __INSERT_TWITCH_CLIENT_ID_HERE__

View File

@ -1,5 +1,6 @@
appdirs==1.4.3
CacheControl==0.12.6
cachetools==4.1.1
certifi==2019.11.28
chardet==3.0.4
click==7.1.2
@ -7,7 +8,6 @@ colorama==0.4.3
contextlib2==0.6.0
distlib==0.3.0
distro==1.4.0
expiringdict==1.2.1
Flask==1.1.2
gunicorn==20.0.4
html5lib==1.0.1

View File

@ -22,14 +22,14 @@ import logging
import re
from os import environ
from feedformatter import Feed
from expiringdict import ExpiringDict
from cachetools import cached, TTLCache, LRUCache
from io import BytesIO
import gzip
VOD_URL_TEMPLATE = 'https://api.twitch.tv/kraken/channels/%s/videos?broadcast_type=archive,highlight,upload&limit=10'
USERID_URL_TEMPLATE = 'https://api.twitch.tv/kraken/users?login=%s'
VODCACHE_LIFETIME = 600
VODCACHE_LIFETIME = 10 * 60
USERIDCACHE_LIFETIME = 24 * 60 * 60
CHANNEL_FILTER = re.compile("^[a-zA-Z0-9_]{2,25}$")
TWITCH_CLIENT_ID = environ.get("TWITCH_CLIENT_ID")
@ -41,9 +41,6 @@ if not TWITCH_CLIENT_ID:
app = Flask(__name__)
vodcache = ExpiringDict(max_len=200, max_age_seconds=VODCACHE_LIFETIME)
useridcache = ExpiringDict(max_len=1000, max_age_seconds=USERIDCACHE_LIFETIME)
@app.route('/vod/<string:channel>', methods=['GET', 'HEAD'])
def vod(channel):
@ -63,31 +60,29 @@ def vodonly(channel):
def get_inner(channel, add_live=True):
userid_json = fetch_userid(channel)
if not userid_json:
abort(404)
(channel_display_name, channel_id) = extract_userid(json.loads(userid_json))
channel_json = fetch_vods(channel_id)
if not channel_json:
abort(404)
decoded_json = json.loads(channel_json)
rss_data = construct_rss(channel, decoded_json, channel_display_name, add_live)
headers = {'Content-Type': 'application/rss+xml'}
return rss_data, headers
@cached(cache=TTLCache(maxsize=2000, ttl=USERIDCACHE_LIFETIME))
def fetch_userid(channel_name):
return fetch_or_cache_object(channel_name, useridcache, USERID_URL_TEMPLATE)
return fetch_json(channel_name, USERID_URL_TEMPLATE)
@cached(cache=TTLCache(maxsize=400, ttl=VODCACHE_LIFETIME))
def fetch_vods(channel_id):
return fetch_or_cache_object(channel_id, vodcache, VOD_URL_TEMPLATE)
def fetch_or_cache_object(key, cachedict, url_template):
json_data = cachedict.get(key)
if not json_data:
json_data = fetch_json(key, url_template)
if not json_data:
abort(404)
else:
cachedict[key] = json_data
return json_data
return fetch_json(channel_id, VOD_URL_TEMPLATE)
def fetch_json(id, url_template):
@ -112,7 +107,7 @@ def fetch_json(id, url_template):
except Exception as e:
logging.warning("Fetch exception caught: %s" % e)
retries += 1
return None
abort(503)
def extract_userid(user_info):