<s> from __future__ import print_function , unicode_literals <EOL> import threading <EOL> import time <EOL> import sys <EOL> import weblab . configuration_doc as configuration_doc <EOL> import voodoo . sessions . generator as SessionGenerator <EOL> import voodoo . sessions . serializer as SessionSerializer <EOL> import voodoo . log as log <EOL> import voodoo . sessions . exc as SessionErrors <EOL> class SessionObj ( object ) : <EOL> def __init__ ( self , obj ) : <EOL> self . latest_change = time . time ( ) <EOL> self . latest_access = self . latest_change <EOL> self . _obj = obj <EOL> def get_obj ( self ) : <EOL> self . latest_access = time . time ( ) <EOL> return self . _obj <EOL> def set_obj ( self , value ) : <EOL> self . latest_change = time . time ( ) <EOL> self . latest_access = self . latest_change <EOL> self . _obj = value <EOL> obj = property ( get_obj , set_obj ) <EOL> def is_expired ( self , timeout ) : <EOL> now = time . time ( ) <EOL> seconds = now - self . latest_access <EOL> return seconds > timeout <EOL> class SessionMemoryGateway ( object ) : <EOL> def __init__ ( self , cfg_manager , session_pool_id , timeout ) : <EOL> object . __init__ ( self ) <EOL> self . _serialize = cfg_manager [ configuration_doc . SESSION_MEMORY_GATEWAY_SERIALIZE ] <EOL> self . _cfg_manager = cfg_manager <EOL> self . _generator = SessionGenerator . SessionGenerator ( ) <EOL> self . _serializer = SessionSerializer . SessionSerializer ( ) <EOL> self . _sessions = { <EOL> } <EOL> self . _session_locks = { <EOL> } <EOL> self . _timeout = timeout <EOL> for first_char in self . _generator . alphabet : <EOL> self . _sessions [ first_char ] = ( threading . RLock ( ) , { } ) <EOL> self . _session_locks [ first_char ] = { } <EOL> def _get_lock_and_sessions ( self , session_id ) : <EOL> if len ( session_id ) == <NUM_LIT:0> : <EOL> raise SessionErrors . SessionNotFoundError ( "<STR_LIT>" ) <EOL> return self . _sessions [ session_id [ : <NUM_LIT:1> ] ] <EOL> def _get_session_lock ( self , session_id ) : <EOL> return self . _session_locks [ session_id [ : <NUM_LIT:1> ] ] <EOL> def delete_expired_sessions ( self ) : <EOL> if self . _timeout is None : <EOL> return <EOL> session_ids = self . list_sessions ( ) <EOL> for session_id in session_ids : <EOL> try : <EOL> session_obj = self . get_session_obj ( session_id ) <EOL> if session_obj . is_expired ( self . _timeout ) : <EOL> self . delete_session ( session_id ) <EOL> except SessionErrors . SessionNotFoundError : <EOL> continue <EOL> except : <EOL> exc , inst , _ = sys . exc_info ( ) <EOL> log . log ( self , log . level . Error , "<STR_LIT>" % ( exc , inst , session_id ) ) <EOL> log . log_exc ( self , log . level . Warning ) <EOL> continue <EOL> def create_session ( self , desired_sess_id = None ) : <EOL> if desired_sess_id is not None : <EOL> lock , sessions = self . _get_lock_and_sessions ( desired_sess_id ) <EOL> lock . acquire ( ) <EOL> if desired_sess_id in sessions : <EOL> lock . release ( ) <EOL> raise SessionErrors . DesiredSessionIdAlreadyExistsError ( "<STR_LIT>" % desired_sess_id ) <EOL> session_id = desired_sess_id <EOL> else : <EOL> must_repeat = True <EOL> while must_repeat : <EOL> session_id = self . _generator . generate_id ( ) <EOL> lock , sessions = self . _get_lock_and_sessions ( session_id ) <EOL> lock . acquire ( ) <EOL> must_repeat = session_id in sessions <EOL> if must_repeat : <EOL> lock . release ( ) <EOL> if self . _serialize : <EOL> obj = self . _serializer . serialize ( { } ) <EOL> else : <EOL> obj = { } <EOL> sessions [ session_id ] = SessionObj ( obj ) <EOL> self . _session_locks [ session_id [ : <NUM_LIT:1> ] ] [ session_id ] = threading . Lock ( ) <EOL> lock . release ( ) <EOL> return session_id <EOL> def has_session ( self , session_id ) : <EOL> lock , sessions = self . _get_lock_and_sessions ( session_id ) <EOL> with lock : <EOL> return session_id in sessions <EOL> def get_session_obj ( self , session_id ) : <EOL> lock , sessions = self . _get_lock_and_sessions ( session_id ) <EOL> with lock : <EOL> if not session_id in sessions : <EOL> raise SessionErrors . SessionNotFoundError ( <EOL> "<STR_LIT>" + session_id <EOL> ) <EOL> session = sessions [ session_id ] <EOL> return session <EOL> def get_session ( self , session_id ) : <EOL> session = self . get_session_obj ( session_id ) <EOL> if self . _serialize : <EOL> return self . _serializer . deserialize ( session . obj ) <EOL> else : <EOL> return session . obj <EOL> def modify_session ( self , sess_id , sess_obj ) : <EOL> if self . _serialize : <EOL> sess_obj = self . _serializer . serialize ( sess_obj ) <EOL> lock , sessions = self . _get_lock_and_sessions ( sess_id ) <EOL> with lock : <EOL> if not sess_id in sessions : <EOL> raise SessionErrors . SessionNotFoundError ( <EOL> "<STR_LIT>" + sess_id <EOL> ) <EOL> sessions [ sess_id ] = SessionObj ( sess_obj ) <EOL> def get_session_locking ( self , session_id ) : <EOL> lock , sessions = self . _get_lock_and_sessions ( session_id ) <EOL> session_locks = self . _get_session_lock ( session_id ) <EOL> with lock : <EOL> session = self . get_session ( session_id ) <EOL> lck = session_locks [ session_id ] <EOL> acquired = lck . acquire ( False ) <EOL> if not acquired : <EOL> lck . acquire ( ) <EOL> session = self . get_session ( session_id ) <EOL> return session <EOL> def modify_session_unlocking ( self , session_id , sess_obj ) : <EOL> lock , sessions = self . _get_lock_and_sessions ( session_id ) <EOL> session_locks = self . _get_session_lock ( session_id ) <EOL> with lock : <EOL> try : <EOL> self . modify_session ( session_id , sess_obj ) <EOL> finally : <EOL> try : <EOL> session_locks [ session_id ] . release ( ) <EOL> except KeyError : <EOL> pass <EOL> def unlock_without_modifying ( self , session_id ) : <EOL> lock , sessions = self . _get_lock_and_sessions ( session_id ) <EOL> session_locks = self . _get_session_lock ( session_id ) <EOL> with lock : <EOL> try : <EOL> session_locks [ session_id ] . release ( ) <EOL> except KeyError : <EOL> pass <EOL> def list_sessions ( self ) : <EOL> total_session_ids = [ ] <EOL> for first_chars in self . _sessions : <EOL> lock , sessions = self . _sessions [ first_chars ] <EOL> with lock : <EOL> for session_id in sessions : <EOL> total_session_ids . append ( session_id ) <EOL> return total_session_ids <EOL> def clear ( self ) : <EOL> """<STR_LIT>""" <EOL> for first_chars in self . _sessions : <EOL> lock , sessions = self . _sessions [ first_chars ] <EOL> session_locks = self . _session_locks [ first_chars ] <EOL> with lock : <EOL> sessions . clear ( ) <EOL> session_locks . clear ( ) <EOL> def delete_session ( self , session_id ) : <EOL> lock , sessions = self . _get_lock_and_sessions ( session_id ) <EOL> session_locks = self . _get_session_lock ( session_id ) <EOL> with lock : <EOL> if session_id in sessions : <EOL> sessions . pop ( session_id ) <EOL> session_locks . pop ( session_id ) <EOL> else : <EOL> raise SessionErrors . SessionNotFoundError ( <EOL> "<STR_LIT>" + session_id <EOL> ) <EOL> def delete_session_unlocking ( self , session_id ) : <EOL> lock , sessions = self . _get_lock_and_sessions ( session_id ) <EOL> session_locks = self . _get_session_lock ( session_id ) <EOL> with lock : <EOL> if session_id in sessions : <EOL> sessions . pop ( session_id ) <EOL> session_lock = session_locks . pop ( session_id ) <EOL> session_lock . release ( ) <EOL> else : <EOL> raise SessionErrors . SessionNotFoundError ( <EOL> "<STR_LIT>" + session_id <EOL> ) </s>
