weird Page Template / ZODB history problem with Zope 2.12.7
Hi All, Try this: - edit a page template - edit it again - go to the history tab, and use the "Copy to present" button to bring back your first edit. On the edit tab, you will correctly see the text you brought back. However, if you render the template, the old text will be used. It's only if you "Save changes" that the copied-to-present text will actually be used. Anyone got any ideas why and how to fix this? cheers, Chris -- Simplistix - Content Management, Batch Processing & Python Consulting - http://www.simplistix.co.uk
On Mon, Sep 27, 2010 at 11:37:11PM +0100, Chris Withers wrote:
Hi All,
Try this:
- edit a page template
- edit it again
- go to the history tab, and use the "Copy to present" button to bring back your first edit.
On the edit tab, you will correctly see the text you brought back. However, if you render the template, the old text will be used.
It's only if you "Save changes" that the copied-to-present text will actually be used.
Anyone got any ideas why and how to fix this?
Why? Because the precompiled TAL bytecode is sitting there in a _v_program attribute that's not stored in the ZODB, so it's not reverted when you undo things. How to fix? Make the "Copy to present" button drop all _v_* attributes from the object it modifies. This is OFS.History.Historical.manage_historyCopy, right? Quick untested patch: --- ./OFS/History.py.orig 2010-09-28 02:11:56.535745440 +0300 +++ ./OFS/History.py 2010-09-28 02:12:00.043764683 +0300 @@ -151,6 +151,9 @@ base = aq_base(self) base._p_activate() # make sure we're not a ghost base.__setstate__(state) # change the state + for attr in dir(base): + if attr.startswith('_v_'): + delattr(base, attr) base._p_changed = True # marke object as dirty self.manage_afterHistoryCopy() Marius Gedminas -- http://pov.lt/ -- Zope 3/BlueBream consulting and development
On 28/09/2010 00:12, Marius Gedminas wrote:
--- ./OFS/History.py.orig 2010-09-28 02:11:56.535745440 +0300 +++ ./OFS/History.py 2010-09-28 02:12:00.043764683 +0300 @@ -151,6 +151,9 @@ base = aq_base(self) base._p_activate() # make sure we're not a ghost base.__setstate__(state) # change the state + for attr in dir(base): + if attr.startswith('_v_'): + delattr(base, attr) base._p_changed = True # marke object as dirty self.manage_afterHistoryCopy()
Thanks, I guess I'll monkey patch for now, here's the bug: https://bugs.launchpad.net/zope2/+bug/649605 However, I'm curious, so the above will fix the object in the current thread, but what about objects in other threads? (or do _v_ attributes get killed off at the start of each transaction?) cheers, Chris -- Simplistix - Content Management, Batch Processing & Python Consulting - http://www.simplistix.co.uk
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 09/28/2010 03:36 AM, Chris Withers wrote:
On 28/09/2010 00:12, Marius Gedminas wrote:
--- ./OFS/History.py.orig 2010-09-28 02:11:56.535745440 +0300 +++ ./OFS/History.py 2010-09-28 02:12:00.043764683 +0300 @@ -151,6 +151,9 @@ base = aq_base(self) base._p_activate() # make sure we're not a ghost base.__setstate__(state) # change the state + for attr in dir(base): + if attr.startswith('_v_'): + delattr(base, attr) base._p_changed = True # marke object as dirty self.manage_afterHistoryCopy()
Thanks, I guess I'll monkey patch for now, here's the bug:
https://bugs.launchpad.net/zope2/+bug/649605
However, I'm curious, so the above will fix the object in the current thread, but what about objects in other threads?
(or do _v_ attributes get killed off at the start of each transaction?)
Only when objects are ghostified (due to an invalidation from another thread or process) or evicted from the cache. I'm not quite sure how the case you are triggering occurs, but if that code saves the new-old version of the template to the ZODB, then any instances in other threads' connection caches should be invalidated. Tres. - -- =================================================================== Tres Seaver +1 540-429-0999 tseaver@palladion.com Palladion Software "Excellence by Design" http://palladion.com -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkyh17wACgkQ+gerLs4ltQ6RVQCguN4WMtI8LqzJ7LrwIjB0sNAL yjUAoMApTFJXqBqBVtAyxBWwJI1x7dFV =6BKq -----END PGP SIGNATURE-----
On 28/09/2010 12:55, Tres Seaver wrote:
On 09/28/2010 03:36 AM, Chris Withers wrote:
On 28/09/2010 00:12, Marius Gedminas wrote:
--- ./OFS/History.py.orig 2010-09-28 02:11:56.535745440 +0300 +++ ./OFS/History.py 2010-09-28 02:12:00.043764683 +0300 @@ -151,6 +151,9 @@ base = aq_base(self) base._p_activate() # make sure we're not a ghost base.__setstate__(state) # change the state + for attr in dir(base): + if attr.startswith('_v_'): + delattr(base, attr) base._p_changed = True # marke object as dirty self.manage_afterHistoryCopy()
Thanks, I guess I'll monkey patch for now, here's the bug:
https://bugs.launchpad.net/zope2/+bug/649605
However, I'm curious, so the above will fix the object in the current thread, but what about objects in other threads?
(or do _v_ attributes get killed off at the start of each transaction?)
Only when objects are ghostified (due to an invalidation from another thread or process) or evicted from the cache. I'm not quite sure how the case you are triggering occurs, but if that code saves the new-old version of the template to the ZODB, then any instances in other threads' connection caches should be invalidated.
Feel free to repeat the steps I originally posted and are in the bug description ;-) Looks like the History.py code isn't doing something it should, but I don't know when or what changed to make this so. I'll CC zodb-dev in case Jim knows of any changes in ZODB (I'm using 3.9.6) that might be relevant... cheers, Chris -- Simplistix - Content Management, Batch Processing & Python Consulting - http://www.simplistix.co.uk
participants (3)
-
Chris Withers -
Marius Gedminas -
Tres Seaver