[Checkins] [zopefoundation/ZODB] 589f32: Call _p_resolveConflict() even if a conflicting ch...

GitHub noreply at github.com
Tue Sep 13 12:22:20 CEST 2016

  Branch: refs/heads/3.10
  Home:   https://github.com/zopefoundation/ZODB
  Commit: 589f327a89a3abcbaf860db9532829df08bae862
  Author: Julien Muchembled <jm at nexedi.com>
  Date:   2016-09-13 (Tue, 13 Sep 2016)

  Changed paths:
    M src/ZODB/ConflictResolution.py
    M src/ZODB/tests/testconflictresolution.py

  Log Message:
  Call _p_resolveConflict() even if a conflicting change doesn't change the state

This reverts to the behaviour of 3.10.3 and older.

(cherry picked from commit b74eef767952daf6b972511e9bba389be00955be)


  Commit: 524c27143add6cb7e02b9664fff9558bd4dbff9e
  Author: Julien Muchembled <jm at nexedi.com>
  Date:   2016-09-13 (Tue, 13 Sep 2016)

  Changed paths:
    M src/CHANGES.txt

  Log Message:
  Changelog for PR #98

  Commit: 9ddbacb0e07fd51f1a67700b5ff47544f4a91cb5
  Author: Kirill Smelkov <kirr at nexedi.com>
  Date:   2016-09-13 (Tue, 13 Sep 2016)

  Changed paths:
    M src/CHANGES.txt
    M src/persistent/cPersistence.c
    M src/persistent/tests/testPersistent.py

  Log Message:
  persistent: On deactivate release in-slots objects too

( This is backport of https://github.com/zopefoundation/persistent/pull/44
  to ZODB-3.10 )

On ._p_deactivate() and ._p_invalidate(), when an object goes to ghost
state, objects referenced by all its attributes, except related to
persistence machinery, are released, this way freeing memory (if they
were referenced only from going-to-ghost object).

That's the idea - an object in ghost state is simply a stub, which loads
its content on first access (via hooking into get/set attr) while
occupying minimal memory in not-yet-loaded state.

However the above is not completely true right now, as currently on
ghostification only object's .__dict__ is released, while in-slots objects
are retained attached to ghost object staying in RAM:

    ---- 8< ----
    from ZODB import DB
    from persistent import Persistent
    import gc

    db = DB(None)
    jar = db.open()

    class C:
  def __init__(self, v):
      self.v = v
  def __del__(self):
      print 'released (%s)' % self.v

    class P1(Persistent):

    class P2(Persistent):
  __slots__ = ('aaa')

    p1 = P1()
    p1.aaa = C(1)

    p2 = P2()
    p2.aaa = C(2)

    # "released (1)" is printed

    # "released (2)" is NOT printed     <--
    ---- 8< ----

So teach ghostify() & friends to release objects in slots to free-up
memory when an object goes to ghost state.

NOTE PyErr_Occurred() added after ghostify() calls because
pickle_slotnames() can raise an error, but we do not want to change
ghostify() prototype for backward compatibility reason - as it is used
in cPersistenceCAPIstruct.

( I hit this bug with wendelin.core which uses proxies to load
  data from DB to virtual memory manager and then deactivate proxy right
  after load has been completed:

  https://lab.nexedi.com/nexedi/wendelin.core/blob/f7803634/bigfile/file_zodb.py#L295 )

Compare: https://github.com/zopefoundation/ZODB/compare/64f3b58f843c...9ddbacb0e07f

More information about the checkins mailing list