Commit 25c90a68 authored by Sascha Herzinger's avatar Sascha Herzinger
Browse files

Added teardown method to ensure the release of the session lock

parent 9a4a481a
......@@ -49,7 +49,7 @@ redis = StrictRedis(host=app.config['REDIS_HOST'],
# Set new session interface for app
log.info("Replacing default session interface.")
app.session_interface = RedisSessionInterface(redis)
app.session_interface = RedisSessionInterface(redis, app)
# allow everyone to submit requests
log.info("Setting up CORS.")
......
"""This module provides sample data."""
import pandas as pd
import numpy as np
from fractalis.data.etl import ETL
class RandomNumericalETL(ETL):
name = 'test_numerical_array_etl'
produces = 'numerical_array'
@staticmethod
def can_handle(handler: str, descriptor: dict) -> bool:
return handler == 'test' and \
descriptor['data_type'] == 'numerical_array'
def extract(self, server: str,
token: str, descriptor: dict) -> pd.DataFrame:
data = pd.DataFrame(np.random.randn(50000, 200).tolist())
return data
def transform(self, raw_data: pd.DataFrame,
descriptor: dict) -> pd.DataFrame:
raw_data.insert(0, 'id', raw_data.index.astype('str'))
df = pd.melt(raw_data, id_vars='id', var_name='feature')
return df
......@@ -5,13 +5,9 @@ class TestHandler(ETLHandler):
_handler = 'test'
def _heartbeat(self):
pass
@staticmethod
def make_label(descriptor):
pass
return descriptor.get('label')
def _get_token_for_credentials(self, server: str,
user: str, passwd: str) -> str:
pass
def _get_token_for_credentials(self, server: str, auth: dict) -> str:
return 'abc'
import json
import logging
from uuid import uuid4
from time import sleep
from werkzeug.datastructures import CallbackDict
from flask import session
from flask.sessions import SessionMixin, SessionInterface
logger = logging.getLogger(__name__)
class RedisSession(CallbackDict, SessionMixin):
def __init__(self, sid, initial=None):
......@@ -21,11 +26,27 @@ class RedisSession(CallbackDict, SessionMixin):
class RedisSessionInterface(SessionInterface):
def __init__(self, redis):
def __init__(self, redis, app):
self.redis = redis
@app.teardown_request
def teardown_request(exc=None) -> None:
"""Release session lock whatever happens.
:param exc: Unhandled exception that might have been thrown.
"""
try:
app.session_interface.release_lock(session.sid)
except AttributeError:
logger.warning(
"Attempted to release session lock but no session id was "
"found. This happens only during testing and should never "
"happen in production mode.")
def acquire_lock(self, sid, request_id):
if self.redis.get(name='session:{}:lock'.format(sid)) == request_id:
if request_id is None:
return
lock_id = self.redis.get(name='session:{}:lock'.format(sid))
if lock_id == request_id:
return
while self.redis.getset(name='session:{}:lock'.format(sid),
value=request_id):
......@@ -58,7 +79,6 @@ class RedisSessionInterface(SessionInterface):
self.redis.delete('session:{}'.format(session.sid))
response.delete_cookie(app.session_cookie_name,
domain=domain, path=path)
self.release_lock(session.sid)
return
session_expiration_time = app.config['PERMANENT_SESSION_LIFETIME']
cookie_expiration_time = self.get_expiration_time(app, session)
......@@ -66,7 +86,6 @@ class RedisSessionInterface(SessionInterface):
self.redis.setex(name='session:{}'.format(session.sid),
time=session_expiration_time,
value=serialzed_session_data)
self.release_lock(session.sid)
response.set_cookie(key=app.session_cookie_name, value=session.sid,
expires=cookie_expiration_time, httponly=True,
domain=domain)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment