[Zope3-checkins] SVN: Zope3/branches/stub-session/src/zope/app/session/ RAMSessionDataContainer for in-memory session data. Not ZEO compatible.

Stuart Bishop zen at shangri-la.dropbear.id.au
Wed May 26 22:11:09 EDT 2004


Log message for revision 25036:
RAMSessionDataContainer for in-memory session data. Not ZEO compatible.



-=-
Modified: Zope3/branches/stub-session/src/zope/app/session/__init__.py
===================================================================
--- Zope3/branches/stub-session/src/zope/app/session/__init__.py	2004-05-27 02:05:33 UTC (rev 25035)
+++ Zope3/branches/stub-session/src/zope/app/session/__init__.py	2004-05-27 02:11:08 UTC (rev 25036)
@@ -11,14 +11,12 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""Simplistic session service implemented using cookies.
+"""
+Session implementation using cookies
 
-This is more of a demonstration than a full implementation, but it should
-work.
-
 $Id$
 """
-import sha, time, string, random, hmac, logging
+import sha, time, string, random, hmac, logging, warnings, thread
 from UserDict import IterableUserDict
 from heapq import heapify, heappop
 
@@ -26,6 +24,7 @@
 from zope.server.http.http_date import build_http_date
 from zope.interface import implements
 from zope.interface.common.mapping import IMapping
+from zope.component import ComponentLookupError
 from zope.app import zapi
 from BTrees.OOBTree import OOBTree
 from zope.app.utility.interfaces import ILocalUtility
@@ -35,6 +34,9 @@
                        ISessionDataContainer, ISession
 from zope.app.container.interfaces import IContained
 
+import ZODB
+import ZODB.MappingStorage
+
 cookieSafeTrans = string.maketrans("+/", "-.")
 
 def digestEncode(s):
@@ -117,7 +119,6 @@
                     path=request.getApplicationURL(path_only=True)
                     )
 
-
     def getBrowserId(self, request):
         ''' See zope.app.interfaces.utilities.session.IBrowserIdManager '''
         sid = self.getRequestId(request)
@@ -163,7 +164,43 @@
             else:
                 return
 
+_ram_session_storages = {}
 
+class RAMSessionDataContainer(PersistentSessionDataContainer):
+    ''' A SessionDataContainer that stores data in RAM. Currently session
+        data is not shared between Zope clients, so server affinity will
+        need to be maintained to use this in a ZEO cluster.
+    '''
+    def __init__(self):
+        self.sweepInterval = 5*60
+        self.key = sha.new(str(time.time() + random.random())).hexdigest()
+
+    _ram_storage = ZODB.MappingStorage.MappingStorage()
+    _conns = {}
+
+    def _getData(self):
+
+        # XXX: Nuke
+        if not hasattr(self, 'key'):
+            self.key = sha.new(str(time.time() + random.random())).hexdigest()
+
+        # Open a connection to _ram_storage per thread
+        tid = thread.get_ident()
+        if not self._conns.has_key(tid):
+            db = ZODB.DB(self._ram_storage)
+            self._conns[tid] = db.open()
+
+        root = self._conns[tid].root()
+        if not root.has_key(self.key):
+            root[self.key] = OOBTree()
+        return root[self.key]
+
+        logger = logging.getLogger('zope.app.session')
+        logger.error('Oops %r' % (_ram_session_storages.keys(),))
+        
+    data = property(_getData, None)
+
+
 class SessionData(Persistent, IterableUserDict):
     ''' Mapping nodes in the ISessionDataContainer tree '''
     implements(IMapping)
@@ -202,7 +239,15 @@
             into a single object.
     '''
     if session_data_container is None:
-        dc = zapi.getUtility(ISessionDataContainer, product_id)
+        try:
+            dc = zapi.getUtility(ISessionDataContainer, product_id)
+        except ComponentLookupError:
+            warnings.warn(
+                    'Unable to find ISessionDataContainer named %s. '
+                    'Using default' % repr(product_id),
+                    RuntimeWarning
+                    )
+            dc = zapi.getUtility(ISessionDataContainer)
     elif ISessionDataContainer.providedBy(session_data_container):
         dc = session_data_container
     else:

Modified: Zope3/branches/stub-session/src/zope/app/session/browser.zcml
===================================================================
--- Zope3/branches/stub-session/src/zope/app/session/browser.zcml	2004-05-27 02:05:33 UTC (rev 25035)
+++ Zope3/branches/stub-session/src/zope/app/session/browser.zcml	2004-05-27 02:11:08 UTC (rev 25036)
@@ -1,8 +1,9 @@
 <configure 
   xmlns:zope="http://namespaces.zope.org/zope"
   xmlns="http://namespaces.zope.org/browser">
-<!-- Cookie Browser Id Manager -->
 
+  <!-- Cookie Browser Id Manager -->
+
   <addMenuItem
     title="Cookie Browser Id Manager"
     description="Uses a cookie to uniquely identify a browser, allowing 
@@ -26,7 +27,7 @@
     name="edit.html" menu="zmi_views" title="Edit"
     permission="zope.ManageContent" />
 
-<!-- PersistentSessionDataContainer -->
+  <!-- PersistentSessionDataContainer -->
 
   <addMenuItem
     title="Persistent Session Data Container"
@@ -34,9 +35,18 @@
     class=".PersistentSessionDataContainer"
     permission="zope.ManageContent" />
 
+  <!-- RAMSessionDataContainer -->
+
+  <addMenuItem
+    title="RAM Session Data Container"
+    description="Stores session data in RAM"
+    class=".RAMSessionDataContainer"
+    permission="zope.ManageContent" />
+
+  <!-- ISessionDataContainer -->
   <editform
     schema=".interfaces.ISessionDataContainer"
-    label="Persistent Session Data Container Properties"
+    label="Session Data Container Properties"
     name="edit.html" menu="zmi_views" title="Edit"
     permission="zope.ManageContent" />
 

Modified: Zope3/branches/stub-session/src/zope/app/session/configure.zcml
===================================================================
--- Zope3/branches/stub-session/src/zope/app/session/configure.zcml	2004-05-27 02:05:33 UTC (rev 25035)
+++ Zope3/branches/stub-session/src/zope/app/session/configure.zcml	2004-05-27 02:11:08 UTC (rev 25036)
@@ -28,6 +28,17 @@
         permission="zope.ManageContent" />
   </content>
 
+  <content class=".RAMSessionDataContainer">
+    <implements
+        interface=".interfaces.ISessionDataContainer"/>
+    <require
+        interface=".interfaces.ISessionDataContainer"
+        permission="zope.Public" />
+    <require
+        set_schema=".interfaces.ISessionDataContainer"
+        permission="zope.ManageContent" />
+  </content>
+
   <include file="browser.zcml" />
 
 </configure>

Modified: Zope3/branches/stub-session/src/zope/app/session/tests.py
===================================================================
--- Zope3/branches/stub-session/src/zope/app/session/tests.py	2004-05-27 02:05:33 UTC (rev 25035)
+++ Zope3/branches/stub-session/src/zope/app/session/tests.py	2004-05-27 02:11:08 UTC (rev 25036)
@@ -30,7 +30,7 @@
 
 from zope.app.session import \
         CookieBrowserIdManager, Session, SessionData, getSession, \
-        PersistentSessionDataContainer
+        PersistentSessionDataContainer, RAMSessionDataContainer
 
 from zope.publisher.interfaces.http import IHTTPRequest
 from zope.publisher.http import HTTPRequest
@@ -117,7 +117,7 @@
     True
     """
 
-def test_PersistentSessionIdContainer():
+def test_PersistentSessionDataContainer():
     """
     Ensure mapping interface is working as expected
 
@@ -159,6 +159,13 @@
     'stale'
     """
 
+def test_RAMSessionDataContainer(self):
+    pass
+test_RAMSessionDataContainer.__doc__ = \
+        test_PersistentSessionDataContainer.__doc__.replace(
+            'PersistentSessionDataContainer', 'RAMSessionDataContainer'
+            )
+
 def test_Session():
     """
     >>> data_container = PersistentSessionDataContainer()
@@ -241,6 +248,7 @@
     >>> session1 = getSession(root, request, 'products.foo')
     >>> session2 = getSession(root, request, 'products.bar', 'persistent')
     >>> session3 = getSession(root, request, 'products.baz', pdc)
+    >>> session4 = getSession(root, request, 'products.foo')
 
     Make sure it returned sane values
 
@@ -251,7 +259,7 @@
     >>> ISession.providedBy(session3)
     True
 
-    Make sure that product_ids don't share a namespace
+    Make sure that product_ids don't share a namespace, except when they should
 
     >>> session1['color'] = 'red'
     >>> session2['color'] = 'blue'
@@ -259,6 +267,8 @@
     'red'
     >>> session2['color']
     'blue'
+    >>> session4['color']
+    'red'
 
     >>> setup.placefulTearDown()
     >>> 'Thats all folks!'




More information about the Zope3-Checkins mailing list