-
Notifications
You must be signed in to change notification settings - Fork 310
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
494 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#!/usr/bin/env python | ||
# -*- coding:utf-8 -*- | ||
|
||
# Copyright 2014 Mitchell Chu | ||
|
||
"""This is a Tornado Session Extension """ | ||
|
||
from __future__ import absolute_import, division, print_function, with_statement | ||
|
||
version = "1.1.5.1" | ||
version_info = (1, 1, 5, 1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#!/usr/bin/env python | ||
# -*- coding:utf-8 -*- | ||
# | ||
# Copyright (c) 2014 Mitchell Chu | ||
|
||
import sys | ||
|
||
# __all__ = ( | ||
# 'text_type', 'string_types', 'izip', 'iteritems', 'itervalues', | ||
# 'with_metaclass', | ||
# ) | ||
|
||
PY3 = sys.version_info >= (3,) | ||
|
||
if PY3: | ||
text_type = str | ||
string_types = (str, ) | ||
integer_types = int | ||
izip = zip | ||
_xrange = range | ||
MAXSIZE = sys.maxsize | ||
|
||
def iteritems(o): | ||
return iter(o.items()) | ||
|
||
def itervalues(o): | ||
return iter(o.values()) | ||
|
||
def bytes_from_hex(h): | ||
return bytes.fromhex(h) | ||
|
||
def reraise(exctype, value, trace=None): | ||
raise exctype(str(value)).with_traceback(trace) | ||
|
||
def _unicode(s): | ||
return s | ||
else: | ||
text_type = unicode | ||
string_types = (basestring, ) | ||
integer_types = (int, long) | ||
from itertools import izip | ||
_xrange = xrange | ||
MAXSIZE = sys.maxint | ||
|
||
def b(s): | ||
# See comments above. In python 2.x b('foo') is just 'foo'. | ||
return s | ||
|
||
def iteritems(o): | ||
return o.iteritems() | ||
|
||
def itervalues(o): | ||
return o.itervalues() | ||
|
||
def bytes_from_hex(h): | ||
return h.decode('hex') | ||
|
||
# "raise x, y, z" raises SyntaxError in Python 3 | ||
exec("""def reraise(exctype, value, trace=None): | ||
raise exctype, str(value), trace | ||
""") | ||
|
||
_unicode = unicode | ||
|
||
|
||
def with_metaclass(meta, base=object): | ||
return meta("NewBase", (base,), {}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Copyright @ 2014 Mitchell Chu | ||
|
||
from __future__ import (absolute_import, division, print_function, | ||
with_statement) | ||
|
||
|
||
class SessionDriver(object): | ||
''' | ||
abstact class for all real session driver implements. | ||
''' | ||
def __init__(self, **settings): | ||
self.settings = settings | ||
|
||
def get(self, session_id): | ||
raise NotImplementedError() | ||
|
||
def save(self, session_id, session_data, expires=None): | ||
raise NotImplementedError() | ||
|
||
def clear(self, session_id): | ||
raise NotImplementedError() | ||
|
||
def remove_expires(self): | ||
raise NotImplementedError() | ||
|
||
class SessionDriverFactory(object): | ||
''' | ||
session driver factory | ||
use input settings to return suitable driver's instance | ||
''' | ||
@staticmethod | ||
def create_driver(driver, **settings): | ||
module_name = 'jupyter_server.torndsession.%ssession' % driver.lower() | ||
module = __import__(module_name, globals(), locals(), ['object']) | ||
# must use this form. | ||
# use __import__('torndsession.' + driver.lower()) just load torndsession.__init__.pyc | ||
cls = getattr(module, '%sSession' % driver.capitalize()) | ||
if not 'SessionDriver' in [base.__name__ for base in cls.__bases__]: | ||
raise InvalidSessionDriverException( | ||
'%s not found in current driver implements ' % driver) | ||
return cls | ||
|
||
|
||
class InvalidSessionDriverException(Exception): | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Copyright @ 2014 Mitchell Chu | ||
|
||
from __future__ import (absolute_import, division, print_function, | ||
with_statement) | ||
|
||
from datetime import datetime | ||
|
||
from .driver import SessionDriver | ||
from .session import SessionConfigurationError | ||
from .compat import iteritems | ||
|
||
|
||
class MemorySession(SessionDriver): | ||
""" | ||
save session data in process memory | ||
""" | ||
|
||
MAX_SESSION_OBJECTS = 1024 | ||
"""The max session objects save in memory. | ||
when session objects count large than this value, | ||
system will auto to clear the expired session data. | ||
""" | ||
|
||
def __init__(self, **settings): | ||
# check settings | ||
super(MemorySession, self).__init__(**settings) | ||
host = settings.get("host") | ||
if not host: | ||
raise SessionConfigurationError( | ||
'memory session driver can not found persistence position') | ||
if not hasattr(host, "session_container"): | ||
setattr(host, "session_container", {}) | ||
self._data_handler = host.session_container | ||
|
||
def get(self, session_id): | ||
""" | ||
get session object from host. | ||
""" | ||
if session_id not in self._data_handler: | ||
return {} | ||
|
||
session_obj = self._data_handler[session_id] | ||
now = datetime.utcnow() | ||
expires = session_obj.get('__expires__', now) | ||
if expires > now: | ||
return session_obj | ||
return {} | ||
|
||
def save(self, session_id, session_data, expires=None): | ||
""" | ||
save session data to host. | ||
if host's session objects is more then MAX_SESSION_OBJECTS | ||
system will auto to clear expired session data. | ||
after cleared, system will add current to session pool, however the pool is full. | ||
""" | ||
session_data = session_data or {} | ||
if expires: | ||
session_data.update(__expires__=expires) | ||
if len(self._data_handler) >= self.MAX_SESSION_OBJECTS: | ||
self.remove_expires() | ||
if len(self._data_handler) >= self.MAX_SESSION_OBJECTS: | ||
print("system session pool is full. need more memory to save session object.") | ||
self._data_handler[session_id] = session_data | ||
|
||
def clear(self, session_id): | ||
if self._data_handler.haskey(session_id): | ||
del self._data_handler[session_id] | ||
|
||
def remove_expires(self): | ||
keys = [] | ||
for key, val in iteritems(self._data_handler): | ||
now = datetime.utcnow() | ||
expires = val.get("__expires__", now) | ||
if now >= expires: | ||
keys.append(key) | ||
for key in keys: | ||
del self._data_handler[key] |
Oops, something went wrong.