Skip to content
Snippets Groups Projects
Commit af3b0512 authored by Bjarke Madsen's avatar Bjarke Madsen
Browse files

make endpoint synchronous now that the process is fast

parent d1e3aeef
No related branches found
No related tags found
No related merge requests found
import datetime import datetime
import logging
from flask import jsonify, Response from flask import jsonify, Response
from concurrent.futures import ThreadPoolExecutor
from flask import Blueprint, current_app from flask import Blueprint, current_app
from brian_dashboard_manager.routes import common from brian_dashboard_manager.routes import common
from brian_dashboard_manager.grafana.provision import provision from brian_dashboard_manager.grafana.provision import provision
from brian_dashboard_manager import CONFIG_KEY from brian_dashboard_manager import CONFIG_KEY
logger = logging.getLogger(__name__)
provision_state = { provision_state = {
'time': datetime.datetime.now(datetime.timezone.utc), 'time': datetime.datetime.now(datetime.timezone.utc),
'provisioning': False 'provisioning': False
...@@ -29,13 +31,17 @@ def after_request(resp): ...@@ -29,13 +31,17 @@ def after_request(resp):
return common.after_request(resp) return common.after_request(resp)
def provision_maybe(): @routes.route('/', methods=['GET'])
def update():
""" """
Check if we should provision in case of multiple requests hitting the endpoint. This resource is used to trigger the dashboard provisioning to Grafana.
We need to make sure we don't provision if another thread is still running.
The response will be formatted according to the following schema:
.. asjson::
brian_dashboard_manager.routes.update.UPDATE_RESPONSE_SCHEMA
:return: tuple of (bool, datetime) representing if we can provision :return: json
and the timestamp of the last provisioning, respectively.
""" """
global provision_state # noqa: F824 global provision_state # noqa: F824
...@@ -43,9 +49,10 @@ def provision_maybe(): ...@@ -43,9 +49,10 @@ def provision_maybe():
now = datetime.datetime.now(datetime.timezone.utc) now = datetime.datetime.now(datetime.timezone.utc)
timestamp = provision_state['time'] timestamp = provision_state['time']
provisioning = provision_state['provisioning'] provisioning = provision_state['provisioning']
should = True
if provisioning and (now - timestamp).total_seconds() < 600: # lockout for 10 minutes at most if provisioning and (now - timestamp).total_seconds() < 300: # lockout for 5 minutes at most
return False, timestamp should = False
def write_timestamp(timestamp, provisioning): def write_timestamp(timestamp, provisioning):
provision_state['time'] = timestamp provision_state['time'] = timestamp
...@@ -55,32 +62,18 @@ def provision_maybe(): ...@@ -55,32 +62,18 @@ def provision_maybe():
now = datetime.datetime.now(datetime.timezone.utc) now = datetime.datetime.now(datetime.timezone.utc)
write_timestamp(now, False) write_timestamp(now, False)
write_timestamp(now, True) if should:
write_timestamp(now, True)
executor = ThreadPoolExecutor(max_workers=1)
f = executor.submit(provision, current_app.config[CONFIG_KEY])
f.add_done_callback(lambda _: _finish())
return True, now
@routes.route('/', methods=['GET'])
def update():
"""
This resource is used to trigger the provisioning to Grafana.
It responds to the request immediately after starting
the provisioning process.
The response will be formatted according to the following schema:
.. asjson:: try:
brian_dashboard_manager.routes.update.UPDATE_RESPONSE_SCHEMA provision(current_app.config[CONFIG_KEY])
except Exception:
logger.exception("Error during provisioning:")
return jsonify({'data': {'message': 'Provisioning failed, check logs for details.'}}), 500
finally:
_finish()
:return: json return jsonify({'data': {'message': 'Provisioned dashboards!'}})
"""
should, timestamp = provision_maybe()
if should:
return jsonify({'data': {'message': 'Provisioning dashboards!'}})
else: else:
seconds_ago = (datetime.datetime.now(datetime.timezone.utc) - timestamp).total_seconds() seconds_ago = (datetime.datetime.now(datetime.timezone.utc) - timestamp).total_seconds()
message = f'Provision already in progress since {timestamp} ({seconds_ago:.2f} seconds ago).' message = f'Provision already in progress since {timestamp} ({seconds_ago:.2f} seconds ago).'
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment