Commit fe491771 authored by Chris McDonough's avatar Chris McDonough

Minor test, documentation, and appearance changes according to some of Amos' comments.

parent ae5b894f
...@@ -24,12 +24,11 @@ undoing ZODB databases. ...@@ -24,12 +24,11 @@ undoing ZODB databases.
</p> </p>
<p> <p>
Transient Object Containers support <b>Notification Targets</b> which Transient Object Containers support <b>Add and Delete Scripts</b> which
are methods which are invoked when transient objects are added or deleted are methods which are invoked when transient objects are added or deleted
from the container. A notification target is invoked with the item being from the container. A add/delete script is invoked with the item being
operated upon, and the transient object container as arguments. For the add operated upon and the transient object container as arguments. Specify
and delete notification targets, specify the Zope physical path to the the Zope physical path to the method to be invoked to receive the notification
method to be invoked to receive the notification
(e.g. '/folder/add_notifier'). (e.g. '/folder/add_notifier').
</p> </p>
</div> </div>
...@@ -71,7 +70,7 @@ method to be invoked to receive the notification ...@@ -71,7 +70,7 @@ method to be invoked to receive the notification
<TR> <TR>
<TD ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT" VALIGN="TOP">
<div class="form-label"> <div class="form-label">
<em>Add Notification Target</em> <em>Script to call upon object add</em>
</div> </div>
</TD> </TD>
<TD ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT" VALIGN="TOP">
...@@ -82,7 +81,7 @@ method to be invoked to receive the notification ...@@ -82,7 +81,7 @@ method to be invoked to receive the notification
<TR> <TR>
<TD ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT" VALIGN="TOP">
<div class="form-label"> <div class="form-label">
<em>Delete Notification Target</em> <em>Script to call upon object delete</em>
</div> </div>
</TD> </TD>
<TD ALIGN="LEFT" VALIGN="TOP"> <TD ALIGN="LEFT" VALIGN="TOP">
......
...@@ -7,6 +7,16 @@ ...@@ -7,6 +7,16 @@
<table cellspacing="2"> <table cellspacing="2">
<form action="manage_changeTransientObjectContainer" method="post"> <form action="manage_changeTransientObjectContainer" method="post">
<tr><td>&nbsp;</td></tr>
<tr>
<td class="form-help" colspan=2>
Transient Object Containers are used to store transient data.
Transient data will persist, but only for a user-specified period of time
(the "data object timeout") after which it will be flushed.
</td>
</tr>
<tr><td>&nbsp;</td></tr>
<tr> <tr>
<td align="left" valign="top"> <td align="left" valign="top">
<div class="form-label"> <div class="form-label">
...@@ -24,11 +34,13 @@ ...@@ -24,11 +34,13 @@
</div> </div>
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
&nbsp; &nbsp;
</td> </td>
</tr> </tr>
<tr> <tr>
<td align="left" valign="top"> <td align="left" valign="top">
<div class="form-label"> <div class="form-label">
...@@ -36,7 +48,7 @@ ...@@ -36,7 +48,7 @@
</div> </div>
</td> </td>
<td align="left" valign="top"> <td align="left" valign="top">
<input type="text" name="title" size=20 value="&dtml-title;"> <input type="text" name="title" size=30 value="&dtml-title;">
</td> </td>
</tr> </tr>
<tr> <tr>
...@@ -54,7 +66,7 @@ ...@@ -54,7 +66,7 @@
<tr> <tr>
<td align="left" valign="top"> <td align="left" valign="top">
<div class="form-label"> <div class="form-label">
Add Notification Target Script to call when objects are added
</div> </div>
</td> </td>
<td align="left" valign="top"> <td align="left" valign="top">
...@@ -66,7 +78,7 @@ ...@@ -66,7 +78,7 @@
<tr> <tr>
<td align="left" valign="top"> <td align="left" valign="top">
<div class="form-label"> <div class="form-label">
Delete Notification Target Script to call when objects are deleted
</div> </div>
</td> </td>
<td align="left" valign="top"> <td align="left" valign="top">
...@@ -82,7 +94,7 @@ ...@@ -82,7 +94,7 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td align="center" valign="top"> <td align="center" valign="top" colspan=2>
<input class="form-element" type=submit name=submit value=" Change "> <input class="form-element" type=submit name=submit value=" Change ">
</td> </td>
</tr> </tr>
...@@ -92,7 +104,7 @@ ...@@ -92,7 +104,7 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td align="left" valign="top"> <td align="left" valign="top" colspan=2>
<div class="form-label"> <div class="form-label">
<font color="red">WARNING!</font> <font color="red">WARNING!</font>
The data objects existing in this transient object container The data objects existing in this transient object container
......
...@@ -2,49 +2,63 @@ TransientObjectContainer - Add ...@@ -2,49 +2,63 @@ TransientObjectContainer - Add
Transient Object Containers Transient Object Containers
A TransientObjectContainer contains objects which will expire after A Transient Object Container contains objects which expire after
a given period of time. A TransientObjectContainer is used by a user-settable period of time. Items placed into transient object
SessionDataMangers to store session information. must have string keys, but may have any type of value.
To create a TransientObjectContainer, specify the following: Common Usages
- **id** A Transient Object Container is used by Session Data Mangers to store
session data.
The ID of the TransientObjectContainer is the container's name. To create a Transient Object Container, specify the following:
- *title* - **Id**
The Zope id of the Transient Object Container.
- *Title*
The title of the object. The title of the object.
- **timeout_minutes** - **Data object timeout in minutes**
The minimum number of minutes that objects in the container will The minimum number of minutes that objects in the container will
persist for. Objects in the container are passively deleted, so persist for. Objects in the container are passively deleted, so
they may not be deleted exactly after timeout_minutes elapses. they may not be deleted exactly after this number of minutes elapses.
- *Script to call when objects are added*
The physical path of of a Zope script which will receive notifications
when objects are added to the Transient Object Container.
Ex: '/path/to/add/script'.
- *addNotification* For more information, see "Add and Delete Scripts" below.
The name of an object to receive notifications when objects are - *Script to call when objects are deleted*
added to the TransientObjectContainer. See NotificationTargets.
- *delNotification* The physical path of a Zope script which will receive notifications
when objects are deleted from the Transient Object Container, either
explicitly or through timeout-related expiration.
The name of an object to receive notifications when objects are Ex: '/path/to/delete/script'
deleted from the TransientObjectContainer. See NotificationTargets.
For more information, see "Add and Delete Scripts" below.
Notification Targets
A NotificationTarget is a callable (a bound method, function, or Add and Delete Scripts
named Zope object) which is called when an object is added or removed
from a TransientObjectContainer.
NotificationTargets are called with two arguments, the first being Add and Delete scripts are Zope scripts which are called,
the item being added or removed from the container, and the second respectively, when an object is added or removed from a
being the container itself. Within Zope, the container will be Transient Object Container. An add or delete script is specified
acquisition wrapped, allowing the container to be used as a context by naming it by its full Zope object path with slash separators,
to reference other Zope objects. e.g. "/path/to/method".
Add and delete scripts are called with two arguments. The first
argument is the item being added or removed from the container;
the second argument is the Transient Object Container itself.
The container will be acquisition wrapped, allowing the
it to be used as a context to reference other Zope objects.
See Also See Also
......
...@@ -2,57 +2,72 @@ TransientObjectContainer - Manage ...@@ -2,57 +2,72 @@ TransientObjectContainer - Manage
Transient Object Containers Transient Object Containers
A TransientObjectContainer contains objects which will expire after A Transient Object Container contains objects which expire after
a given period of time. A TransientObjectContainer is used by a user-settable period of time. Items placed into transient object
a SessionDataManager to store session data. must have string keys, but may have any type of value.
To change a TransientObjectContainer, specify the following: Common Usages
- **Title** A Transient Object Container is used by Session Data Mangers to store
session data.
The title of the object (optional). To create a Transient Object Container, specify the following:
- **Id**
The Zope id of the Transient Object Container.
- *Title*
The title of the object.
- **Data object timeout in minutes** - **Data object timeout in minutes**
The minimum number of minutes that objects in the container will The minimum number of minutes that objects in the container will
persist for. Objects in the container are passively deleted, so persist for. Objects in the container are passively deleted, so
they may not be deleted exactly after timeout_minutes elapses. they may not be deleted exactly after this number of minutes elapses.
If you change the timeout value, all objects in the transient If you change the timeout value, all objects in the transient
container will be flushed. container will be flushed.
The default is 20 minutes. - *Script to call when objects are added*
- **Add Notification Target** The physical path of of a Zope script which will receive notifications
when objects are added to the Transient Object Container.
The physical path of a script which will receive notifications when Ex: '/path/to/add/script'.
objects are added to the TransientObjectContainer. See
NotificationTargets below. Ex: '/path/to/addNotificationMethod'.
- **Delete Notification Target** For more information, see "Add and Delete Scripts" below.
The physical path of a script which will receive notifications when - *Script to call when objects are deleted*
objects are deleted from the TransientObjectContainer. See
NotificationTargets below. Ex: 'path/to/delNotificationMethod'.
Notification Targets
A NotificationTarget is a string representing a physical path to a The physical path of a Zope script which will receive notifications
Zope Script (Python Script or External Method) object which is when objects are deleted from the Transient Object Container, either
called when an object is added or removed from a explicitly or through timeout-related expiration.
TransientObjectContainer.
Notification targets are called with two arguments, the first Ex: '/path/to/delete/script'
being the item being added or removed from the container, and the
second being the container itself. Within Zope, the container
will be acquisition wrapped, allowing the container to be used as
a context to reference other Zope objects.
An example of a notification target External Method:: For more information, see "Add and Delete Scripts" below.
def notificationTarget(item, container): Add and Delete Scripts
from zLOG import LOG
LOG(100, 'test', 'id: %s' % item.getId()) Add and Delete scripts are Zope scripts which are called,
respectively, when an object is added or removed from a
Transient Object Container. An add or delete script is specified
by naming it by its full Zope object path with slash separators,
e.g. "/path/to/method".
Add and delete scripts are called with two arguments. The first
argument is the item being added or removed from the container;
the second argument is the Transient Object Container itself.
The container will be acquisition wrapped, allowing the
it to be used as a context to reference other Zope objects.
An example of an External Method used as a delete script::
def deleteScript(item, container):
from zLOG import LOG
LOG(100, 'test', 'id: %s' % item.getId())
See Also See Also
......
...@@ -3,14 +3,12 @@ import sys, os, time, unittest ...@@ -3,14 +3,12 @@ import sys, os, time, unittest
if __name__=='__main__': if __name__=='__main__':
sys.path.insert(0, '..') sys.path.insert(0, '..')
sys.path.insert(0, '../../..') sys.path.insert(0, '../../..')
#os.chdir('../../..')
import ZODB # in order to get Persistence.Persistent working import ZODB # in order to get Persistence.Persistent working
from Testing import makerequest from Testing import makerequest
import Acquisition import Acquisition
from Acquisition import aq_base from Acquisition import aq_base
from Products.Transience.Transience import TransientObjectContainer from Products.Transience.Transience import TransientObjectContainer
from Products.Transience.Transience import WRITEGRANULARITY
import Products.Transience.Transience import Products.Transience.Transience
from Products.PythonScripts.PythonScript import PythonScript from Products.PythonScripts.PythonScript import PythonScript
from ZODB.POSException import InvalidObjectReference from ZODB.POSException import InvalidObjectReference
...@@ -19,7 +17,7 @@ from unittest import TestCase, TestSuite, TextTestRunner, makeSuite ...@@ -19,7 +17,7 @@ from unittest import TestCase, TestSuite, TextTestRunner, makeSuite
from ZODB.DemoStorage import DemoStorage from ZODB.DemoStorage import DemoStorage
from OFS.Application import Application from OFS.Application import Application
import time, threading, whrandom import time, threading, whrandom
WRITEGRANULARITY = 30
epoch = time.time() epoch = time.time()
stuff = {} stuff = {}
...@@ -55,39 +53,27 @@ def _delApp(): ...@@ -55,39 +53,27 @@ def _delApp():
class TestBase(TestCase): class TestBase(TestCase):
def setUp(self): def setUp(self):
Products.Transience.Transience.time = fauxtime Products.Transience.Transience.time = fauxtime
self.app = makerequest.makerequest(_getApp()) self.app = makerequest.makerequest(_getApp())
timeout = self.timeout = 1 timeout = self.timeout = 1
sm=TransientObjectContainer( sm=TransientObjectContainer(
id='sm', timeout_mins=timeout, title='SessionThing', id='sm', timeout_mins=timeout, title='SessionThing',
addNotification=addNotificationTarget, addNotification=addNotificationTarget,
delNotification=delNotificationTarget) delNotification=delNotificationTarget)
self.app._setObject('sm', sm) self.app._setObject('sm', sm)
def tearDown(self): def tearDown(self):
get_transaction().abort() get_transaction().abort()
#self.app._p_jar.close()
#self.app = None
_delApp() _delApp()
del self.app del self.app
class TestLastAccessed(TestBase): class TestLastAccessed(TestBase):
def testLastAccessed(self): def testLastAccessed(self):
sdo = self.app.sm.new_or_existing('TempObject') sdo = self.app.sm.new_or_existing('TempObject')
la1 = sdo.getLastAccessed() la1 = sdo.getLastAccessed()
fauxsleep(WRITEGRANULARITY + 1) fauxsleep(WRITEGRANULARITY + 1)
sdo = self.app.sm['TempObject'] sdo = self.app.sm['TempObject']
assert sdo.getLastAccessed() > la1, (sdo.getLastAccessed(), la1)
assert sdo.getLastAccessed() > la1
class TestNotifications(TestBase): class TestNotifications(TestBase):
def testAddNotification(self): def testAddNotification(self):
...@@ -103,8 +89,7 @@ class TestNotifications(TestBase): ...@@ -103,8 +89,7 @@ class TestNotifications(TestBase):
sdo = self.app.sm.new_or_existing('TempObject') sdo = self.app.sm.new_or_existing('TempObject')
timeout = self.timeout * 60 timeout = self.timeout * 60
fauxsleep(timeout + (timeout * .33)) fauxsleep(timeout + (timeout * .33))
try: try: sdo1 = self.app.sm['TempObject']
sdo1 = self.app.sm['TempObject']
except KeyError: pass except KeyError: pass
now = fauxtime() now = fauxtime()
k = sdo.get('endtime') k = sdo.get('endtime')
...@@ -112,11 +97,9 @@ class TestNotifications(TestBase): ...@@ -112,11 +97,9 @@ class TestNotifications(TestBase):
assert k <= now assert k <= now
def addNotificationTarget(item, context): def addNotificationTarget(item, context):
#print "addNotificationTarget called for %s" % item
item['starttime'] = fauxtime() item['starttime'] = fauxtime()
def delNotificationTarget(item, context): def delNotificationTarget(item, context):
#print "delNotificationTarget called for %s" % item
item['endtime'] = fauxtime() item['endtime'] = fauxtime()
def fauxtime(): def fauxtime():
......
...@@ -382,7 +382,7 @@ class TestTransientObjectContainer(TestCase): ...@@ -382,7 +382,7 @@ class TestTransientObjectContainer(TestCase):
self.t._reset() self.t._reset()
for x in range(10, 110): for x in range(10, 110):
self.t[x] = x self.t[x] = x
fauxsleep(self.timeout) fauxsleep(self.timeout * (self.errmargin+1))
assert len(self.t.keys()) == 100, len(self.t.keys()) assert len(self.t.keys()) == 100, len(self.t.keys())
fauxsleep(self.timeout * (self.errmargin+1)) fauxsleep(self.timeout * (self.errmargin+1))
assert len(self.t.keys()) == 0, len(self.t.keys()) assert len(self.t.keys()) == 0, len(self.t.keys())
...@@ -392,9 +392,9 @@ class TestTransientObjectContainer(TestCase): ...@@ -392,9 +392,9 @@ class TestTransientObjectContainer(TestCase):
self.t._reset() self.t._reset()
for x in range(10, 110): for x in range(10, 110):
self.t[x] = x self.t[x] = x
fauxsleep(self.timeout) fauxsleep(self.timeout * (self.errmargin+1))
assert len(self.t.keys()) == 100, len(self.t.keys()) assert len(self.t.keys()) == 100, len(self.t.keys())
fauxsleep(self.timeout) fauxsleep(self.timeout * (self.errmargin+1))
assert len(self.t.keys()) == 100, len(self.t.keys()) assert len(self.t.keys()) == 100, len(self.t.keys())
fauxsleep(self.timeout * (self.errmargin+1)) fauxsleep(self.timeout * (self.errmargin+1))
assert len(self.t.keys()) == 0, len(self.t.keys()) assert len(self.t.keys()) == 0, len(self.t.keys())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment