Sessions infrastructure for new server

This commit is contained in:
Kovid Goyal 2015-10-11 13:47:55 +05:30
parent 65c6d6d86c
commit 23a6c43552
2 changed files with 71 additions and 2 deletions

View File

@ -15,6 +15,7 @@ from threading import Lock
from calibre.db.cache import Cache
from calibre.db.legacy import create_backend, LibraryDatabase
from calibre.srv.routes import Router
from calibre.srv.session import Sessions
from calibre.utils.date import utcnow
def init_library(library_path):
@ -71,18 +72,21 @@ class Context(object):
url_for = None
CATEGORY_CACHE_SIZE = 25
SEARCH_CACHE_SIZE = 100
SESSION_COOKIE = 'calibre_session'
def __init__(self, libraries, opts, testing=False):
self.opts = opts
self.library_broker = LibraryBroker(libraries)
self.testing = testing
self.lock = Lock()
self.sessions = Sessions()
def init_session(self, endpoint, data):
pass
data.session = self.sessions.get_or_create(key=data.cookies.get(self.SESSION_COOKIE), username=data.username)
def finalize_session(self, endpoint, data, output):
pass
data.outcookie[self.SESSION_COOKIE] = data.session.key
data.outcookie[self.SESSION_COOKIE]['path'] = self.url_for(None)
def get_library(self, library_id=None):
return self.library_broker.get(library_id)

View File

@ -0,0 +1,65 @@
#!/usr/bin/env python2
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
from __future__ import (unicode_literals, division, absolute_import,
print_function)
from copy import deepcopy
from uuid import uuid4
from threading import Lock
from calibre.utils.lru_cache import lru_cache
defaults = {
'sort': 'date:asc',
'library_id': None,
}
class Session(object):
def __init__(self):
self._data = deepcopy(defaults)
def __getitem__(self, key):
return self._data[key]
def __setitem__(self, key, val):
self._data[key] = val
class SessionProxy(object):
''' Prevent the creation of a long-lived session object for every new
request without a session cookie. Instead, this object lives only as long
an individual request, and unless some setting is changed from the default
simply returns values from the global defaults object. '''
def __init__(self, sessions, key):
self.sessions = sessions
self.key = key
self.actual_session = None
def __getitem__(self, key):
if self.actual_session is None:
return defaults[key]
return self.actual_session[key]
def __setitem__(self, key, val):
with self.sessions.lock:
if self.actual_session is None:
self.actual_session = self.sessions.cache[self.key] = Session()
self.actual_session[key] = val
class Sessions(object):
def __init__(self):
self.cache = lru_cache(size=2000)
self.lock = Lock()
def get_or_create(self, key=None, username=None):
key = key or str(uuid4()).replace('-', '')
try:
with self.lock:
return self.cache[key]
except KeyError:
return SessionProxy(self, key)