1.1 --- a/WebStack/Helpers/Session.py Sun Nov 20 21:17:57 2005 +0000
1.2 +++ b/WebStack/Helpers/Session.py Sun Nov 20 21:18:09 2005 +0000
1.3 @@ -21,46 +21,37 @@
1.4 """
1.5
1.6 import shelve
1.7 -import os
1.8 -import time
1.9 import random
1.10 import sys
1.11 +from WebStack.Repositories.Directory import DirectoryRepository
1.12
1.13 class SessionStore:
1.14
1.15 "A class representing a session store."
1.16
1.17 - def __init__(self, trans, session_directory, session_cookie_name="SID", concurrent=1, delay=1):
1.18 + def __init__(self, trans, session_directory, session_cookie_name="SID", delay=1):
1.19
1.20 """
1.21 Initialise the session store, specifying the transaction 'trans' within
1.22 - which all session access will occur, a base 'session_directory', the
1.23 + which all session access will occur, a base 'session_directory', and the
1.24 optional 'session_cookie_name' where the session identifier is held for
1.25 - each user, and specifying using the optional 'concurrent' parameter
1.26 - whether concurrent access within the framework might occur (1) or
1.27 - whether the framework queues accesses at some other level (0). The
1.28 - optional 'delay' argument specifies the time in seconds between each
1.29 + each user.
1.30 +
1.31 + The optional 'delay' argument specifies the time in seconds between each
1.32 poll of the session file when that file is found to be locked for
1.33 - editing.
1.34 + editing. (This is part of the underlying repository's behaviour.)
1.35 """
1.36
1.37 self.trans = trans
1.38 - self.session_directory = session_directory
1.39 self.session_cookie_name = session_cookie_name
1.40 - self.concurrent = concurrent
1.41 - self.delay = delay
1.42 + self.repository = DirectoryRepository(session_directory, delay=delay)
1.43
1.44 # Internal state.
1.45
1.46 self.store = None
1.47 - self.store_filename, self.edit_filename = None, None
1.48 + self.current_session_id = None
1.49 self.to_expire = None
1.50
1.51 - # Attempt to create a session directory if it does not exist.
1.52 -
1.53 - if not os.path.exists(self.session_directory):
1.54 - os.mkdir(self.session_directory)
1.55 -
1.56 def close(self):
1.57
1.58 "Close the store, tidying up files and filenames."
1.59 @@ -68,12 +59,9 @@
1.60 if self.store is not None:
1.61 self.store.close()
1.62 self.store = None
1.63 - if self.edit_filename is not None:
1.64 - try:
1.65 - os.rename(self.edit_filename, self.store_filename)
1.66 - except OSError:
1.67 - pass
1.68 - self.edit_filename, self.store_filename = None, None
1.69 + if self.current_session_id is not None:
1.70 + self.repository.unlock(self.current_session_id)
1.71 + self.current_session_id = None
1.72
1.73 # Handle expiry appropriately.
1.74
1.75 @@ -95,26 +83,9 @@
1.76
1.77 def _expire_session(self, session_id):
1.78
1.79 - """
1.80 - Expire the session with the given 'session_id'. Note that in concurrent
1.81 - session stores, this operation will block if another execution context
1.82 - is editing the session.
1.83 - """
1.84 + "Expire the session with the given 'session_id'."
1.85
1.86 - filename = os.path.join(self.session_directory, session_id)
1.87 - if self.concurrent:
1.88 - while 1:
1.89 - try:
1.90 - os.unlink(filename)
1.91 - except OSError:
1.92 - time.sleep(self.delay)
1.93 - else:
1.94 - break
1.95 - else:
1.96 - try:
1.97 - os.unlink(filename)
1.98 - except OSError:
1.99 - pass
1.100 + del self.repository[session_id]
1.101
1.102 def get_session(self, create):
1.103
1.104 @@ -149,39 +120,13 @@
1.105 Returns a dictionary-like object representing the session.
1.106 """
1.107
1.108 - filename = os.path.join(self.session_directory, session_id)
1.109 -
1.110 - # Enforce locking.
1.111 -
1.112 - if self.concurrent:
1.113 -
1.114 - # Where the session is present (possibly being edited)...
1.115 -
1.116 - if os.path.exists(filename) or os.path.exists(filename + ".edit"):
1.117 - while 1:
1.118 - try:
1.119 - os.rename(filename, filename + ".edit")
1.120 - except OSError:
1.121 - time.sleep(self.delay)
1.122 - else:
1.123 - break
1.124 -
1.125 - # Where no session is present and none should be created, return.
1.126 -
1.127 - elif not create:
1.128 - return None
1.129 -
1.130 - self.store_filename = filename
1.131 - filename = filename + ".edit"
1.132 - self.edit_filename = filename
1.133 -
1.134 - # For non-concurrent situations, return if no session exists and none
1.135 - # should be created.
1.136 -
1.137 - elif not os.path.exists(filename) and not create:
1.138 + try:
1.139 + store_filename = self.repository.lock(session_id, create=create, opener=shelve.open)
1.140 + self.current_session_id = session_id
1.141 + except KeyError:
1.142 return None
1.143
1.144 - self.store = shelve.open(filename)
1.145 + self.store = shelve.open(store_filename)
1.146 return Wrapper(self.store)
1.147
1.148 def _get_session_identifier(self):