mirror of https://github.com/muk-it/muk_base
MuK IT GmbH
6 years ago
3 changed files with 151 additions and 152 deletions
-
2muk_session_store/__manifest__.py
-
122muk_session_store/store/postgres.py
-
179muk_session_store/store/redis.py
@ -1,93 +1,88 @@ |
|||||
import json |
|
||||
################################################################################### |
|
||||
# |
|
||||
# Copyright (C) 2017 MuK IT GmbH |
|
||||
# |
|
||||
# This program is free software: you can redistribute it and/or modify |
|
||||
# it under the terms of the GNU Affero General Public License as |
|
||||
# published by the Free Software Foundation, either version 3 of the |
|
||||
# License, or (at your option) any later version. |
|
||||
# |
|
||||
# This program is distributed in the hope that it will be useful, |
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
# GNU Affero General Public License for more details. |
|
||||
# |
|
||||
# You should have received a copy of the GNU Affero General Public License |
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
||||
# |
|
||||
################################################################################### |
|
||||
|
|
||||
import pickle |
|
||||
import logging |
|
||||
import functools |
|
||||
|
|
||||
from werkzeug.contrib.sessions import SessionStore |
|
||||
|
|
||||
from odoo.tools import config |
|
||||
|
|
||||
_logger = logging.getLogger(__name__) |
|
||||
|
|
||||
try: |
|
||||
import redis |
|
||||
except ImportError: |
|
||||
pass |
|
||||
|
|
||||
SESSION_TIMEOUT = 60 * 60 * 24 * 7 |
|
||||
|
|
||||
def ensure_server(func): |
|
||||
@functools.wraps(func) |
|
||||
def wrapper(self, *args, **kwargs): |
|
||||
for attempts in range(1, 6): |
|
||||
try: |
|
||||
return func(self, *args, **kwargs) |
|
||||
except redis.ConnectionError as error: |
|
||||
_logger.info("SessionStore connection failed! (%s/5)" % attempts) |
|
||||
if attempts >= 5: |
|
||||
raise error |
|
||||
return wrapper |
|
||||
|
|
||||
class RedisSessionStore(SessionStore): |
|
||||
|
|
||||
def __init__(self, *args, **kwargs): |
|
||||
super(RedisSessionStore, self).__init__(*args, **kwargs) |
|
||||
self.prefix = config.get('session_store_prefix', '') |
|
||||
self.server = redis.Redis( |
|
||||
host=config.get('session_store_host', 'localhost'), |
|
||||
port=int(config.get('session_store_port', 6379)), |
|
||||
db=int(config.get('session_store_dbindex', 1)), |
|
||||
password=config.get('session_store_pass', None) |
|
||||
) |
|
||||
self._check_server() |
|
||||
|
|
||||
def _encode_session_key(self, kex): |
|
||||
return key.encode('utf-8') if isinstance(key, str) else key |
|
||||
|
|
||||
def _get_session_key(self, sid): |
|
||||
return self._encode_session_key(self.key_prefix + sid) |
|
||||
|
|
||||
@ensure_server |
|
||||
def _check_server(self): |
|
||||
self.server.ping() |
|
||||
|
|
||||
@ensure_server |
|
||||
def save(self, session): |
|
||||
key = self._get_session_key(session.sid) |
|
||||
payload = pickle.dumps(dict(session), pickle.HIGHEST_PROTOCOL) |
|
||||
self.server.setex(name=key, value=payload, time=SESSION_TIMEOUT) |
|
||||
|
|
||||
@ensure_server |
|
||||
def delete(self, session): |
|
||||
self.server.delete(self._get_session_key(session.sid)) |
|
||||
|
|
||||
@ensure_server |
|
||||
def get(self, sid): |
|
||||
if not self.is_valid_key(sid): |
|
||||
return self.new() |
|
||||
key = self._get_session_key(sid) |
|
||||
payload = self.server.get(key) |
|
||||
if payload: |
|
||||
self.server.setex(name=key, value=payload, time=SESSION_TIMEOUT) |
|
||||
return self.session_class(pickle.loads(payload), sid, False) |
|
||||
else: |
|
||||
|
import json |
||||
|
################################################################################### |
||||
|
# |
||||
|
# Copyright (C) 2017 MuK IT GmbH |
||||
|
# |
||||
|
# This program is free software: you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU Affero General Public License as |
||||
|
# published by the Free Software Foundation, either version 3 of the |
||||
|
# License, or (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU Affero General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU Affero General Public License |
||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
################################################################################### |
||||
|
|
||||
|
import pickle |
||||
|
import logging |
||||
|
import functools |
||||
|
|
||||
|
from werkzeug.contrib.sessions import SessionStore |
||||
|
|
||||
|
from odoo.tools import config |
||||
|
|
||||
|
_logger = logging.getLogger(__name__) |
||||
|
|
||||
|
try: |
||||
|
import redis |
||||
|
except ImportError: |
||||
|
pass |
||||
|
|
||||
|
SESSION_TIMEOUT = 60 * 60 * 24 * 7 |
||||
|
|
||||
|
def retry_redis(func): |
||||
|
@functools.wraps(func) |
||||
|
def wrapper(self, *args, **kwargs): |
||||
|
for attempts in range(1, 6): |
||||
|
try: |
||||
|
return func(self, *args, **kwargs) |
||||
|
except redis.ConnectionError as error: |
||||
|
_logger.warn("SessionStore connection failed! (%s/5)" % attempts) |
||||
|
if attempts >= 5: |
||||
|
raise error |
||||
|
return wrapper |
||||
|
|
||||
|
class RedisSessionStore(SessionStore): |
||||
|
|
||||
|
def __init__(self, *args, **kwargs): |
||||
|
super(RedisSessionStore, self).__init__(*args, **kwargs) |
||||
|
self.prefix = config.get('session_store_prefix', '') |
||||
|
self.server = redis.Redis( |
||||
|
host=config.get('session_store_host', 'localhost'), |
||||
|
port=int(config.get('session_store_port', 6379)), |
||||
|
db=int(config.get('session_store_dbindex', 1)), |
||||
|
password=config.get('session_store_pass', None) |
||||
|
) |
||||
|
|
||||
|
def _encode_session_key(self, kex): |
||||
|
return key.encode('utf-8') if isinstance(key, str) else key |
||||
|
|
||||
|
def _get_session_key(self, sid): |
||||
|
return self._encode_session_key(self.key_prefix + sid) |
||||
|
|
||||
|
@retry_redis |
||||
|
def save(self, session): |
||||
|
key = self._get_session_key(session.sid) |
||||
|
payload = pickle.dumps(dict(session), pickle.HIGHEST_PROTOCOL) |
||||
|
self.server.setex(name=key, value=payload, time=SESSION_TIMEOUT) |
||||
|
|
||||
|
@retry_redis |
||||
|
def delete(self, session): |
||||
|
self.server.delete(self._get_session_key(session.sid)) |
||||
|
|
||||
|
@retry_redis |
||||
|
def get(self, sid): |
||||
|
if not self.is_valid_key(sid): |
||||
|
return self.new() |
||||
|
key = self._get_session_key(sid) |
||||
|
payload = self.server.get(key) |
||||
|
if payload: |
||||
|
self.server.setex(name=key, value=payload, time=SESSION_TIMEOUT) |
||||
|
return self.session_class(pickle.loads(payload), sid, False) |
||||
|
else: |
||||
return self.session_class({}, sid, False) |
return self.session_class({}, sid, False) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue