Gitte Wange wrote at 2003-11-3 10:12 +0100:
....
I said: your counter (any one of them) in the ZODB should become a "BTrees.Length.Length" instance. I thought, this were pretty clear.
Now it's pretty clear :-) I updated the counts to be a BTrees.Length instance instead of just an integer. Looks like it helped but we still see the error sometimes (not as often as before). The code for updating the counts look like this:
def addCount(self, url): """ Add a new count for an url """ counts = self._counts if not url in counts.keys(): counts[url] = Length(0) counter = counts[url] counter.change(1) counts[url] = counter self._counts = counts self._p_changed = 1
Guess the error is raised when assigning the counts to self._counts. I have experienced before that dictinaries don't survive a restart of Zope if not saving them as above but maybe this can work:
Yes, probably. Make your "_counts" an "BTrees.OOBTree.OOBTree" instance (which is itself a persistent object). You can then drop "self._counts= counts" and "self._p_changed = 1".
... def addCount(self, url): """ Add a new count for an url """ if not url in self._counts.keys(): counts = self._counts counts[url] = Length(0) self._counts = counts self._p_changed = 1 counter = self._counts[url] counter.change(1)
Would that work ?
Yes.
That said: you may want to replace the dictionary by a "BTrees.OOBTree.OOBTree" instance. This way, the conflict resolution of "OOBTrees" may prevent (most) concurrent writes to the mapping (when you add new entries to the mapping) causing exceptions. It may not be necessary, though, as you probably rarely add new entries (usually, you will count in already existing counters).
It's very rarely that I will add new entries - all existing pages already exist in the tool.
Then, you *can* stay with a dictionary. But an "OOBTree" would still give you easier code (no "_p_changed = 1"). -- Dieter