mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-17 14:04:20 +01:00
Add healthcheck endpoint and timed_lru_cache function (#2135)
* Add healthcheck endpoint and timed_lru_cache function
This commit is contained in:
34
CTFd/cache/__init__.py
vendored
34
CTFd/cache/__init__.py
vendored
@@ -1,9 +1,43 @@
|
|||||||
|
from functools import lru_cache, wraps
|
||||||
|
from time import monotonic_ns
|
||||||
|
|
||||||
from flask import request
|
from flask import request
|
||||||
from flask_caching import Cache, make_template_fragment_key
|
from flask_caching import Cache, make_template_fragment_key
|
||||||
|
|
||||||
cache = Cache()
|
cache = Cache()
|
||||||
|
|
||||||
|
|
||||||
|
def timed_lru_cache(timeout: int = 300, maxsize: int = 64, typed: bool = False):
|
||||||
|
"""
|
||||||
|
lru_cache implementation that includes a time based expiry
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
seconds (int): Timeout in seconds to clear the WHOLE cache, default = 5 minutes
|
||||||
|
maxsize (int): Maximum Size of the Cache
|
||||||
|
typed (bool): Same value of different type will be a different entry
|
||||||
|
|
||||||
|
Implmentation from https://gist.github.com/Morreski/c1d08a3afa4040815eafd3891e16b945?permalink_comment_id=3437689#gistcomment-3437689
|
||||||
|
"""
|
||||||
|
|
||||||
|
def wrapper_cache(func):
|
||||||
|
func = lru_cache(maxsize=maxsize, typed=typed)(func)
|
||||||
|
func.delta = timeout * 10 ** 9
|
||||||
|
func.expiration = monotonic_ns() + func.delta
|
||||||
|
|
||||||
|
@wraps(func)
|
||||||
|
def wrapped_func(*args, **kwargs):
|
||||||
|
if monotonic_ns() >= func.expiration:
|
||||||
|
func.cache_clear()
|
||||||
|
func.expiration = monotonic_ns() + func.delta
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
|
wrapped_func.cache_info = func.cache_info
|
||||||
|
wrapped_func.cache_clear = func.cache_clear
|
||||||
|
return wrapped_func
|
||||||
|
|
||||||
|
return wrapper_cache
|
||||||
|
|
||||||
|
|
||||||
def make_cache_key(path=None, key_prefix="view/%s"):
|
def make_cache_key(path=None, key_prefix="view/%s"):
|
||||||
"""
|
"""
|
||||||
This function mostly emulates Flask-Caching's `make_cache_key` function so we can delete cached api responses.
|
This function mostly emulates Flask-Caching's `make_cache_key` function so we can delete cached api responses.
|
||||||
|
|||||||
18
CTFd/utils/health/__init__.py
Normal file
18
CTFd/utils/health/__init__.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
from time import monotonic_ns
|
||||||
|
|
||||||
|
from flask import current_app
|
||||||
|
from sqlalchemy_utils import database_exists
|
||||||
|
|
||||||
|
from CTFd.cache import cache, timed_lru_cache
|
||||||
|
|
||||||
|
|
||||||
|
@timed_lru_cache(timeout=30)
|
||||||
|
def check_database():
|
||||||
|
return database_exists(current_app.config["SQLALCHEMY_DATABASE_URI"])
|
||||||
|
|
||||||
|
|
||||||
|
@timed_lru_cache(timeout=30)
|
||||||
|
def check_config():
|
||||||
|
value = monotonic_ns()
|
||||||
|
cache.set("healthcheck", value)
|
||||||
|
return cache.get("healthcheck") == value
|
||||||
@@ -44,6 +44,7 @@ from CTFd.utils.email import (
|
|||||||
DEFAULT_VERIFICATION_EMAIL_BODY,
|
DEFAULT_VERIFICATION_EMAIL_BODY,
|
||||||
DEFAULT_VERIFICATION_EMAIL_SUBJECT,
|
DEFAULT_VERIFICATION_EMAIL_SUBJECT,
|
||||||
)
|
)
|
||||||
|
from CTFd.utils.health import check_config, check_database
|
||||||
from CTFd.utils.helpers import get_errors, get_infos, markup
|
from CTFd.utils.helpers import get_errors, get_infos, markup
|
||||||
from CTFd.utils.modes import USERS_MODE
|
from CTFd.utils.modes import USERS_MODE
|
||||||
from CTFd.utils.security.auth import login_user
|
from CTFd.utils.security.auth import login_user
|
||||||
@@ -504,3 +505,12 @@ def themes_beta(theme, path):
|
|||||||
if os.path.isfile(cand_path):
|
if os.path.isfile(cand_path):
|
||||||
return send_file(cand_path)
|
return send_file(cand_path)
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
|
|
||||||
|
@views.route("/healthcheck")
|
||||||
|
def healthcheck():
|
||||||
|
if check_database() is False:
|
||||||
|
return "ERR", 500
|
||||||
|
if check_config() is False:
|
||||||
|
return "ERR", 500
|
||||||
|
return "OK", 200
|
||||||
|
|||||||
Reference in New Issue
Block a user