Need a unique gift idea?
A Pastebin account makes a great Christmas gift
SHARE
TWEET

Redis sessions in Nagare

Crumble Jun 18th, 2013 123 Never
Upgrade to PRO!
ENDING IN00days00hours00mins00secs
 
  1. import redis
  2.  
  3. from nagare import local
  4. from nagare.sessions import ExpirationError, common
  5.  
  6. KEY_PREFIX = 'nagare_'
  7.  
  8.  
  9. class Sessions(common.Sessions):
  10.     """Sessions manager for sessions kept in an external redis server
  11.    """
  12.     spec = dict(
  13.         host='string(default="127.0.0.1")',
  14.         port='integer(default=6379)',
  15.         db='integer(default=0)',
  16.         ttl='integer(default=0)',
  17.         lock_ttl='integer(default=0)',
  18.         lock_poll_time='float(default=0.1)',
  19.         reset='boolean(default=True)'
  20.     )
  21.     spec.update(common.Sessions.spec)
  22.  
  23.     def __init__(
  24.         self,
  25.         host='127.0.0.1',
  26.         port=6379,
  27.         db=0,
  28.         ttl=0,
  29.         lock_ttl=5,
  30.         lock_poll_time=0.1,
  31.         reset=False,
  32.         **kw
  33.     ):
  34.         """Initialization
  35.  
  36.        In:
  37.          - ``host`` -- address of the redis server
  38.          - ``port`` -- port of the redis server
  39.          - ``db`` -- redis database id
  40.        """
  41.         super(Sessions, self).__init__(**kw)
  42.  
  43.         self.host = host
  44.         self.port = port
  45.         self.db = db
  46.         self.ttl = ttl
  47.         self.lock_ttl = lock_ttl
  48.         self.lock_poll_time = lock_poll_time
  49.  
  50.         if reset:
  51.             self.flush_all()
  52.  
  53.     def set_config(self, filename, conf, error):
  54.         """Read the configuration parameters
  55.  
  56.        In:
  57.          - ``filename`` -- the path to the configuration file
  58.          - ``conf`` -- the ``ConfigObj`` object, created from the
  59.                        configuration file
  60.          - ``error`` -- the function to call in case of configuration errors
  61.        """
  62.         # Let's the super class validate the configuration file
  63.         conf = super(Sessions, self).set_config(filename, conf, error)
  64.  
  65.         for arg_name in (
  66.             'host', 'port', 'db', 'ttl', 'lock_ttl',
  67.                             'lock_poll_time', 'lock_max_wait_time',
  68.                             'min_compress_len', 'debug'
  69.         ):
  70.             setattr(self, arg_name, conf[arg_name])
  71.  
  72.         if conf['reset']:
  73.             self.flush_all()
  74.  
  75.     def _get_connection(self):
  76.         """Get the connection to the redis server
  77.  
  78.        Return:
  79.          - the connection
  80.        """
  81.         # The connection objects are local to the workers
  82.         connection = getattr(local.worker, 'redis_connection', None)
  83.  
  84.         if connection is None:
  85.             connection = redis.Redis(self.host, self.port, self.db)
  86.             local.worker.redis_connection = connection
  87.  
  88.         return connection
  89.  
  90.     def flush_all(self):
  91.         """Delete all the contents in the redis server
  92.        """
  93.         connection = self._get_connection()
  94.         connection.flushdb()
  95.  
  96.     def _create(self, session_id, secure_id):
  97.         """Create a new session
  98.  
  99.        In:
  100.          - ``session_id`` -- id of the session
  101.          - ``secure_id`` -- the secure number associated to the session
  102.  
  103.        Return:
  104.          - the tuple:
  105.            - id of this state,
  106.            - session lock
  107.        """
  108.  
  109.         connection, lock = self._get_lock(session_id)
  110.  
  111.         connection = connection.pipeline()
  112.  
  113.         connection.hmset(KEY_PREFIX + session_id, {
  114.                          '_sess_id': secure_id,
  115.                          '_sess_data': None,
  116.                          '_state': '0',
  117.                          '00000': {}
  118.                          })
  119.         if self.ttl:
  120.             connection.expire(KEY_PREFIX + session_id, self.ttl)
  121.  
  122.         connection.execute()
  123.  
  124.         return (0, lock)
  125.  
  126.     def _get_lock(self, session_id):
  127.         connection = self._get_connection()
  128.         lock = connection.lock('%slock_%s' % (KEY_PREFIX, session_id),
  129.                                self.lock_ttl,
  130.                                self.lock_poll_time)
  131.         lock.acquire()
  132.         return connection, lock
  133.  
  134.     def _get(self, session_id, state_id, use_same_state):
  135.         """Retrieve the state
  136.  
  137.        In:
  138.          - ``session_id`` -- session id of this state
  139.          - ``state_id`` -- id of this state
  140.          - ``use_same_state`` -- is a copy of this state to create ?
  141.  
  142.        Return:
  143.          - the tuple:
  144.            - id of this state,
  145.            - session lock,
  146.            - secure number associated to the session,
  147.            - data kept into the session
  148.            - data kept into the state
  149.        """
  150.         connection, lock = self._get_lock(session_id)
  151.  
  152.         state_id = state_id.zfill(5)
  153.  
  154.         secure_id, session_data, last_state_id, state_data = connection.hmget(
  155.             KEY_PREFIX + session_id,
  156.             ('_sess_id', '_sess_data', '_state', state_id)
  157.         )
  158.  
  159.         if not (secure_id and session_data and last_state_id and state_data):
  160.             raise ExpirationError()
  161.  
  162.         if not use_same_state:
  163.             state_id = last_state_id
  164.  
  165.         return (int(state_id), lock, secure_id, session_data, state_data)
  166.  
  167.     def _set(self, session_id, state_id, secure_id, use_same_state,
  168.              session_data, state_data):
  169.         """Store the state
  170.  
  171.        In:
  172.          - ``session_id`` -- session id of this state
  173.          - ``state_id`` -- id of this state
  174.          - ``secure_id`` -- the secure number associated to the session
  175.          - ``use_same_state`` -- is this state to be stored in the
  176.                                  previous snapshot ?
  177.          - ``session_data`` -- data keept into the session
  178.          - ``state_data`` -- data keept into the state
  179.        """
  180.         connection = self._get_connection()
  181.  
  182.         connection = connection.pipeline(True)
  183.  
  184.         if not use_same_state:
  185.             connection.hincrby(KEY_PREFIX + session_id, '_state', 1)
  186.  
  187.         connection.hmset(KEY_PREFIX + session_id, {
  188.             '_sess_id': secure_id,
  189.             '_sess_data': session_data,
  190.             '%05d' % state_id: state_data
  191.         })
  192.  
  193.         if self.ttl:
  194.             connection.expire(KEY_PREFIX + session_id, self.ttl)
  195.  
  196.         connection.execute()
  197.  
  198.     def _delete(self, session_id):
  199.         """Delete the session
  200.  
  201.        In:
  202.          - ``session_id`` -- id of the session to delete
  203.        """
  204.         self._get_connection().delete(KEY_PREFIX + session_id)
  205.  
  206.     def serialize(self, data):
  207.         """Pickle an objects graph
  208.  
  209.        In:
  210.          - ``data`` -- the objects graphs
  211.  
  212.        Return:
  213.          - the tuple:
  214.            - data to keep into the session
  215.            - data to keep into the state
  216.        """
  217.         return self.pickle(data)
  218.  
  219.     def deserialize(self, session_data, state_data):
  220.         """Unpickle an objects graph
  221.  
  222.        In:
  223.          - ``session_data`` -- data from the session
  224.          - ``state_data`` -- data from the state
  225.  
  226.        Out:
  227.          - the objects graph
  228.        """
  229.         return self.unpickle(session_data, state_data)
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top