[Zodb-checkins] SVN: ZODB/trunk/src/persistent/interfaces.py
Improve the interface docs.
Tim Peters
tim.one at comcast.net
Tue Jun 22 16:23:48 EDT 2004
Log message for revision 25944:
Improve the interface docs.
-=-
Modified: ZODB/trunk/src/persistent/interfaces.py
===================================================================
--- ZODB/trunk/src/persistent/interfaces.py 2004-06-22 19:33:00 UTC (rev 25943)
+++ ZODB/trunk/src/persistent/interfaces.py 2004-06-22 20:23:47 UTC (rev 25944)
@@ -40,16 +40,16 @@
- Sticky
- This state is identical to the up-to-date state except that the
- object cannot transition to the ghost state. This is a special
+ This state is identical to the saved state except that the
+ object cannot transition to the ghost state. This is a special
state used by C methods of persistent objects to make sure that
state is not unloaded in the middle of computation.
In this state, the _p_changed attribute is non-None and false
and the _p_jar attribute is set to a data manager.
- There is, currently, no official way to detect whether an object
- is in the sticky state.
+ There is no Python API for detecting whether an object is in the
+ sticky state.
- Changed
@@ -61,15 +61,22 @@
- Ghost
the object is in memory but its state has not been loaded from
- the database (or has been unloaded). In this state, the object
- doesn't contain any data.
+ the database (or its state has been unloaded). In this state,
+ the object doesn't contain any application data.
+ In this state, the _p_changed attribute is None, and the _p_jar
+ attribute is set to the data manager from which the object was
+ obtained.
+
+ In all the above, _p_oid (the persistent object id) is set when
+ _p_jar first gets set.
+
The following state transactions are possible:
- Unsaved -> Saved
This transition occurs when an object is saved in the
- database. This usually happens when an unsaved object is added
+ database. This usually happens when an unsaved object is added
to (e.g. as an attribute or item of) a saved (or changed) object
and the transaction is committed.
@@ -77,37 +84,37 @@
Sticky -> Changed
This transition occurs when someone sets an attribute or sets
- _p_changed to a true value on an up-to-date or sticky
- object. When the transition occurs, the persistent object is
- required to call the register method on its data manager,
- passing itself as the only argument.
+ _p_changed to a true value on a saved or sticky object. When the
+ transition occurs, the persistent object is required to call the
+ register() method on its data manager, passing itself as the
+ only argument.
- Saved -> Sticky
This transition occurs when C code marks the object as sticky to
- prevent its deactivation and transition to the ghost state.
+ prevent its deactivation.
- Saved -> Ghost
- This transition occurs when an saved object is deactivated, by:
- calling _p_deactivate, setting _p_changed to None, or deleting
- _p_changed.
+ This transition occurs when a saved object is deactivated or
+ invalidated. See discussion below.
- Sticky -> Saved
This transition occurs when C code unmarks the object as sticky to
- allow its deactivation and transition to the ghost state.
+ allow its deactivation.
- Changed -> Saved
- This transition occurs when a transaction is committed.
- The data manager affects the transaction by setting _p_changed
- to a true value.
+ This transition occurs when a transaction is committed. After
+ saving the state of a changed object during transaction commit,
+ the data manager sets the object's _p_changed to a non-None false
+ value.
- Changed -> Ghost
- This transition occurs when a transaction is aborted.
- The data manager affects the transaction by deleting _p_changed.
+ This transition occurs when a transaction is aborted. All changed
+ objects are invalidated by the data manager by an abort.
- Ghost -> Saved
@@ -116,102 +123,120 @@
Note that there is a separate C API that is not included here.
The C API requires a specific data layout and defines the sticky
- state that is used to prevent object deactivation while in C
- routines.
+ state.
+
+ About Invalidation, Deactivation and the Sticky & Ghost States
+
+ The sticky state is intended to be a short-lived state, to prevent
+ an object's state from being discarded while we're in C routines. It
+ is an error to invalidate an object in the sticky state.
+
+ Deactivation is a request that an object discard its state (become
+ a ghost). Deactivation is an optimization, and a request to
+ deactivate may be ignored. There are two equivalent ways to
+ request deactivation:
+
+ - call _p_deactivate()
+ - set _p_changed to None
+
+ There is one way to invalidate an object: delete its _p_changed
+ attribute. This cannot be ignored, and is used when semantics
+ require invalidation. Normally, an invalidated object transitions
+ to the ghost state. However, some objects cannot be ghosts. When
+ these objects are invalidated, they immediately reload their state
+ from their data manager, and are then in the saved state.
+
"""
- _p_jar=Attribute(
- """The data manager for the object
+ _p_jar = Attribute(
+ """The data manager for the object.
The data manager implements the IPersistentDataManager interface.
If there is no data manager, then this is None.
""")
- _p_oid=Attribute(
- """The object id
+ _p_oid = Attribute(
+ """The object id.
It is up to the data manager to assign this.
The special value None is reserved to indicate that an object
- id has not been assigned.
+ id has not been assigned. Non-None object ids must be hashable
+ and totally ordered.
""")
- _p_changed=Attribute(
+ _p_changed = Attribute(
"""The persistent state of the object
This is one of:
- None -- The object is a ghost. It is not active.
+ None -- The object is a ghost.
- false -- The object is saved (or has never been saved).
+ false but not None -- The object is saved (or has never been saved).
- true -- The object has been modified.
+ true -- The object has been modified since it was last saved.
- The object state may be changed by assigning this attribute,
- however, assigning None is ignored if the object is not in the
- up-to-date state.
+ The object state may be changed by assigning or deleting this
+ attribute; however, assigning None is ignored if the object is
+ not in the saved state, and may be ignored even if the object is
+ in the saved state.
- Note that an object can change to the modified state only if
- it has a data manager. When such a state change occurs, the
- 'register' method of the data manager is called, passing the
+ Note that an object can transition to the changed state only if
+ it has a data manager. When such a state change occurs, the
+ 'register' method of the data manager must be called, passing the
persistent object.
- Deleting this attribute forces deactivation independent of
- existing state.
-
- Note that an attribute is used for this to allow optimized
- cache implementations.
+ Deleting this attribute forces invalidation independent of
+ existing state, although it is an error if the sticky state is
+ current.
""")
- _p_serial=Attribute(
- """The object serial number
+ _p_serial = Attribute(
+ """The object serial number.
- This is an arbitrary object.
- """)
+ This member is used by the data manager to distiguish distinct
+ revisions of a given persistent object.
- _p_atime=Attribute(
- """The integer object access time, in seconds, modulus one day
-
- XXX When does a day start, the current implementation appears
- to use gmtime, but this hasn't be explicitly specified.
-
- XXX Why just one day?
+ This is an 8-byte string (not Unicode).
""")
def __getstate__():
- """Get the object state data
+ """Get the object data.
- The state should not include persistent attributes ("_p_name")
+ The state should not include persistent attributes ("_p_name").
+ The result must be picklable.
"""
def __setstate__(state):
- """Set the object state data
-
- Note that this does not affect the object's persistent state.
+ """Set the object data.
"""
def _p_activate():
- """Activate the object
+ """Activate the object.
- Change the object to the up-to-date state if it is a ghost.
+ Change the object to the saved state if it is a ghost.
"""
def _p_deactivate():
- """Deactivate the object
+ """Deactivate the object.
- If possible, change an object in the up-to-date state to the
+ Possibly change an object in the saved state to the
ghost state. It may not be possible to make some persistent
- objects ghosts.
+ objects ghosts, and, for optimization reasons, the implementation
+ may choose to keep an object in the saved state.
"""
class IPersistentNoReadConflicts(IPersistent):
def _p_independent():
- """Hook for subclasses to prevent read conflict errors
+ """Hook for subclasses to prevent read conflict errors.
A specific persistent object type can define this method and
have it return true if the data manager should ignore read
conflicts for this object.
"""
+
+# XXX TODO: document conflict resolution.
+
class IPersistentDataManager(Interface):
"""Provide services for managing persistent state.
@@ -222,36 +247,34 @@
def setstate(object):
"""Load the state for the given object.
- The object should be in the deactivated (ghost) state.
+ The object should be in the ghost state.
The object's state will be set and the object will end up
- in the up-to-date state.
+ in the saved state.
- The object must implement the IPersistent interface.
+ The object must provide the IPersistent interface.
"""
def register(object):
- """Register a IPersistent with the current transaction.
+ """Register an IPersistent with the current transaction.
- This method provides some insulation of the persistent object
- from details of transaction management. For example, it allows
- the use of per-database-connection rather than per-thread
- transaction managers.
-
- A persistent object should not register with its data manager
- more than once during a single transaction. XXX should is too
- wishy-washy; we should probably guarantee that this is true,
- and it might be.
+ This method must be called when the object transitions to
+ the changed state.
"""
def mtime(object):
"""Return the modification time of the object.
The modification time may not be known, in which case None
- is returned.
+ is returned. If non-None, the return value is the kind of
+ timestamp supplied by Python's time.time().
"""
+# XXX Should we keep the following? Doesn't seem too useful, and
+# XXX we don't actually implement this interface (e.g., we have no
+# XXX .statistics() method).
+
class ICache(Interface):
- """In-memory object cache
+ """In-memory object cache.
The cache serves two purposes. It peforms pointer swizzling, and
it keeps a bounded set of recently used but otherwise unreferenced
More information about the Zodb-checkins
mailing list