Commit b4fa6640 authored by matt@zope.com's avatar matt@zope.com

Moved RAMDB to TemporaryFolder product

parent e9dd7bc9
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
from ZODB.Connection import Connection
from ZODB.POSException import ConflictError
from cPickle import Unpickler
from cStringIO import StringIO
from common import DEBUG
class LowConflictConnection(Connection):
def setstate(self, object):
"""
Unlike the 'stock' Connection class' setstate, this method
doesn't raise ConflictErrors. This is potentially dangerous
for applications that need absolute consistency, but
sessioning is not one of those.
"""
oid=object._p_oid
invalid = self._invalid
if invalid(None):
# only raise a conflict if there was
# a mass invalidation, but not if we see this
# object's oid as invalid
raise ConflictError, `oid`
p, serial = self._storage.load(oid, self._version)
file=StringIO(p)
unpickler=Unpickler(file)
unpickler.persistent_load=self._persistent_load
unpickler.load()
state = unpickler.load()
if hasattr(object, '__setstate__'):
object.__setstate__(state)
else:
d=object.__dict__
for k,v in state.items(): d[k]=v
object._p_serial=serial
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
"""Mounted database support
$Id: RAM_DB.py,v 1.2 2001/11/01 19:20:34 matt Exp $"""
__version__='$Revision: 1.2 $'[11:-2]
import Globals
from Globals import HTMLFile
from ZODB.Mount import MountPoint
import string
import OFS
import os, os.path
ADD_RAMDB_PERM="Add RAM Databases"
def constructRAMDB(self, id, title=None, REQUEST=None):
""" """
ms = MountedRAM_DB(id, title)
self._setObject(id, ms)
if REQUEST is not None:
return self.manage_main(self, REQUEST, update_menu=1)
constructRAMDBForm=HTMLFile('dtml/addRAMDB', globals())
class MountedRAM_DB(MountPoint, OFS.SimpleItem.Item):
"""
A mounted RAM database with a basic interface for displaying the
reason the database did not connect.
"""
icon = 'p_/broken'
manage_options = ({'label':'Traceback', 'action':'manage_traceback'},)
meta_type = 'Broken Mounted RAM Database'
def __init__(self, id, title='', params=None):
self.id = str(id)
self.title = title
MountPoint.__init__(self, path='/') # Eep
manage_traceback = Globals.DTMLFile('dtml/mountfail', globals())
def _createDB(self, db=None): # huh? db=db was original
""" Create a mounted RAM database """
from SessionStorage import SessionStorage
from ZODB.DB import DB
from LowConflictConnection import LowConflictConnection
db = DB(SessionStorage())
db.klass = LowConflictConnection
return db
def _getMountRoot(self, root):
sdc = root.get('folder', None)
if sdc is None:
sdc = root['folder'] = OFS.Folder.Folder()
self._populate(sdc, root)
return sdc
def mount_error_(self):
return self._v_connect_error
def _populate(self, folder, root):
# Set up our folder object
folder.id = self.id # be a chameleon
folder.title = self.title
folder.icon = "misc_/Sessions/ramdb.gif"
importdir = os.path.join(Globals.data_dir,self.id+"Imports")
#conn = folder._p_jar # Can we do that yet?
conn = root._p_jar
try:
for file in os.listdir(importdir):
if file[-5:] == ".zexp":
id = file[:-5]
# Import this!
ob = conn.importFile(os.path.join(importdir, file))
folder._setObject(id, ob)
except OSError: pass # (no such dir)
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
"""
A storage implementation which uses RAM to persist objects, much like
MappingStorage, but unlike MappingStorage needs not be packed to get rid of
non-cyclic garbage. This is a ripoff of Jim's Packless bsddb3 storage.
$Id: SessionStorage.py,v 1.1 2001/10/31 15:36:04 chrism Exp $
"""
__version__ ='$Revision: 1.1 $'[11:-2]
from zLOG import LOG
from struct import pack, unpack
from common import DEBUG
from ZODB.referencesf import referencesf
from ZODB import POSException
from ZODB.BaseStorage import BaseStorage
try:
from ZODB.ConflictResolution import ConflictResolvingStorage
except:
LOG('Session Tracking', 100,
('Not able to use ConflictResolvingStorage for SessionStorage, '
'this is suboptimal. Upgrade to Zope 2.3.2 or later to '
'make use of conflict resolution.'))
class ConflictResolvingStorage: pass
class ReferenceCountError(POSException.POSError):
""" An error occured while decrementing a reference to an object in
the commit phase. The object's reference count was below zero."""
class SessionStorageError(POSException.POSError):
""" A Session Storage exception occurred. This probably indicates that
there is a low memory condition or a tempfile space shortage. Check
available tempfile space and RAM consumption and restart the server
process."""
class SessionStorage(BaseStorage, ConflictResolvingStorage):
def __init__(self, name='SessionStorage'):
"""
index -- mapping of oid to current serial
referenceCount -- mapping of oid to count
oreferences -- mapping of oid to a sequence of its referenced oids
opickle -- mapping of oid to pickle
"""
BaseStorage.__init__(self, name)
self._index={}
self._referenceCount={}
self._oreferences={}
self._opickle={}
self._tmp = []
self._oid = '\0\0\0\0\0\0\0\0'
def __len__(self):
return len(self._index)
def getSize(self):
return 0
def _clear_temp(self):
self._tmp = []
def close(self):
"""
Close the storage
"""
def load(self, oid, version):
self._lock_acquire()
try:
s=self._index[oid]
p=self._opickle[oid]
return p, s # pickle, serial
finally:
self._lock_release()
def loadSerial(self, oid, serial):
""" only a stub to make conflict resolution work! """
self._lock_acquire()
try:
return self._opickle[oid]
finally:
self._lock_release()
def store(self, oid, serial, data, version, transaction):
if transaction is not self._transaction:
raise POSException.StorageTransactionError(self, transaction)
if version:
raise POSException.Unsupported, "Versions aren't supported"
self._lock_acquire()
try:
if self._index.has_key(oid):
oserial=self._index[oid]
if serial != oserial:
if hasattr(self, 'tryToResolveConflict'):
data=self.tryToResolveConflict(
oid, oserial, serial, data
)
if not data:
raise POSException.ConflictError, (serial,oserial)
else:
raise POSException.ConflictError, (serial,oserial)
serial=self._serial
self._tmp.append((oid, data))
return serial
finally:
self._lock_release()
def _finish(self, tid, u, d, e):
zeros={}
referenceCount=self._referenceCount
referenceCount_get=referenceCount.get
oreferences=self._oreferences
serial=self._serial
index=self._index
opickle=self._opickle
# iterate over all the objects touched by/created within this
# transaction
for entry in self._tmp:
oid, data = entry[:]
referencesl=[]
referencesf(data, referencesl)
references={}
for roid in referencesl:
references[roid]=1
referenced=references.has_key
# Create a reference count for this object if one
# doesn't already exist
if referenceCount_get(oid) is None:
referenceCount[oid] = 0
#zeros[oid]=1
# update references that are already associated with this
# object
roids = oreferences.get(oid, [])
for roid in roids:
if referenced(roid):
# still referenced, so no need to update
# remove it from the references dict so it doesn't
# get "added" in the next clause
del references[roid]
else:
# Delete the stored ref, since we no longer
# have it
oreferences[oid].remove(roid)
# decrement refcnt:
rc = referenceCount_get(roid, 1)
rc=rc-1
if rc < 0:
# This should never happen
raise ReferenceCountError, (
"%s (Oid %s had refcount %s)" %
(ReferenceCountError.__doc__,`roid`,rc)
)
referenceCount[roid] = rc
if rc==0:
zeros[roid]=1
# Create a reference list for this object if one
# doesn't already exist
if oreferences.get(oid) is None:
oreferences[oid] = []
# Now add any references that weren't already stored
for roid in references.keys():
oreferences[oid].append(roid)
# Create/update refcnt
rc=referenceCount_get(roid, 0)
if rc==0 and zeros.get(roid) is not None:
del zeros[roid]
referenceCount[roid] = rc+1
index[oid] = serial
opickle[oid] = data
if zeros:
for oid in zeros.keys():
if oid == '\0\0\0\0\0\0\0\0': continue
self._takeOutGarbage(oid)
self._tmp = []
def _takeOutGarbage(self, oid):
# take out the garbage.
referenceCount=self._referenceCount
referenceCount_get=referenceCount.get
try: del referenceCount[oid]
except: pass
try: del self._opickle[oid]
except: pass
try: del self._index[oid]
except: pass
# Remove/decref references
roids = self._oreferences.get(oid, [])
while roids:
roid = roids.pop(0)
# decrement refcnt:
rc=referenceCount_get(roid, 0)
if rc==0:
self._takeOutGarbage(roid)
elif rc < 0:
raise ReferenceCountError, (
"%s (Oid %s had refcount %s)" %
(ReferenceCountError.__doc__,`roid`,rc)
)
else:
referenceCount[roid] = rc - 1
try: del self._oreferences[oid]
except: pass
def pack(self, t, referencesf):
self._lock_acquire()
try:
rindex={}
referenced=rindex.has_key
rootl=['\0\0\0\0\0\0\0\0']
# mark referenced objects
while rootl:
oid=rootl.pop()
if referenced(oid): continue
p = self._opickle[oid]
referencesf(p, rootl)
rindex[oid] = None
# sweep unreferenced objects
for oid in self._index.keys():
if not referenced(oid):
self._takeOutGarbage(oid)
finally:
self._lock_release()
......@@ -85,23 +85,13 @@
"""
Session initialization routines
$Id: __init__.py,v 1.2 2001/11/01 19:20:35 matt Exp $
$Id: __init__.py,v 1.3 2001/11/01 20:19:57 matt Exp $
"""
import BrowserIdManager
import RAM_DB
import SessionDataManager
def initialize(context):
context.registerClass(
RAM_DB.MountedRAM_DB,
permission=RAM_DB.ADD_RAMDB_PERM,
icon='www/ramdb.gif',
meta_type='Temporary Folder',
constructors=(RAM_DB.constructRAMDBForm,
RAM_DB.constructRAMDB)
)
context.registerClass(
BrowserIdManager.BrowserIdManager,
icon="www/idmgr.gif",
......
<dtml-var manage_page_header>
<dtml-var "manage_form_title(this(), _,
form_title='Add Temporary Folder',
help_product='Sessions',
help_topic='Sessions.stx'
)">
<form action="constructRAMDB" method="POST">
<div class="form-help">
<p>
Temporary Folders are in-storage databases, which are created anew at every
initialization of Zope. They are useful for storing temporary objects in.
</p>
</div>
<table cellspacing="2">
<tr>
<td align="LEFT" valign="TOP">
<div class="form-label">
Id
</div>
</td>
<td align="LEFT" valign="TOP">
<input type="TEXT" name="id" size="20" value="temp_folder" />
</td>
</tr>
<tr>
<td align="LEFT" valign="TOP">
<div class="form-label">
<em>Title</em>
</div>
</td>
<td align="LEFT" valign="TOP">
<input type="TEXT" name="title" size="40" />
</td>
</tr>
<tr>
<td></td>
<td><br><input class="form-element" type="SUBMIT" value=" Add "></td>
</tr>
</table>
</form>
<dtml-var manage_page_footer>
<HTML><HEAD><TITLE>Mount Failure Traceback</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" LINK="#000099" VLINK="#555555">
<dtml-var manage_tabs>
<h3>Mount Failure Traceback</h3>
<dtml-let exc=mount_error_>
<dtml-if exc>
<strong>Error type:</strong> <dtml-var "exc[0]" html_quote><br>
<strong>Error value:</strong> <dtml-var "exc[1]" html_quote><br>
<pre>
<dtml-var "exc[2]" html_quote>
</pre>
<dtml-else>
Database not mounted.
</dtml-if>
</dtml-let>
</BODY>
</HTML>
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