[ZCM] [ZC] 2306/10 Comment "Pdata objects can not be Pickled once the chain is longer than 500"

Collector: Zope Bugs, Features, and Patches ... zope-coders-admin at zope.org
Mon Sep 3 10:43:44 EDT 2007


Issue #2306 Update (Comment) "Pdata objects can not be Pickled once the chain is longer than 500"
 Status Pending, Zope/bug medium
To followup, visit:
  http://www.zope.org/Collectors/Zope/2306

==============================================================
= Comment - Entry #10 by tseaver on Sep 3, 2007 10:43 am

I'll note a couple of observations:

 - The chunking into individual 64k Pdata chunks can't work
   when you pass the file to the constructor:  the implementaiton
   relies on having a connection ('_p_jar') already associated
   with the File object, which will never be true ducring the
   constructor.  Therefore, you are likely to end up with a
   *single* Pdata chunk, which will be as large as the entire
   value passed to the constructor.  This is a Bad Thing (tm),
   and is why the 'manage_addFile' factory passes an empty
   string as data to the constructor, and then calls
   'manage_upload' with the real data.

 - Your test is spending a lot of effort getting around
   acquisition wrappers, which can't be pickled properly.
   I *suspect* that the recursion is due to an improperly-
   wrapped object somewhere.
________________________________________
= Comment - Entry #9 by tseaver on Sep 3, 2007 10:38 am

> tseaver:
> You are using Zope 2.10 - the bug is logged against Zope 2.8 and Zope 2.9
>   - maybe it's fixed in 2.10, who knows? Also, you have dumped the data
>   without using the Pickler class - maybe this affects it?

My test script behaves identically in Zope 2.8 and 2.9, and 
if I create a pickler wrapped around 'target' instead of calling
'dump' as a module scope function.


________________________________________
= Comment - Entry #8 by ajung on Sep 3, 2007 6:15 am

The error also occurs with the Python pickle module:

  File "/opt/python-2.4.4/lib/python2.4/pickle.py", line 695, in _batch_setitems
    save(v)
  File "/opt/python-2.4.4/lib/python2.4/pickle.py", line 338, in save
    self.save_reduce(obj=obj, *rv)
  File "/opt/python-2.4.4/lib/python2.4/pickle.py", line 433, in save_reduce
    save(state)
  File "/opt/python-2.4.4/

Also interesting is the behavior of _read_file() generating
only 1 chunk when called through the constructor.
________________________________________
= Comment - Entry #7 by ajung on Sep 2, 2007 6:38 pm

If you submit a bugreport including a test then the test should be as small as possible. I *did* look at the test just because I am also a Plone developer _but_ not everybody as a serveral Plone sandboxes at hand - and especially not if all 3rd-party dependencies like TextIndexNG (as used in your tests)...such tests aren't pretty helpful for us.


________________________________________
= Comment - Entry #6 by esrever_otua on Sep 2, 2007 12:17 pm


Uploaded:  "pdatatest.py"
 - http://www.zope.org/Collectors/Zope/2306/pdatatest.py/view
Attached is a single file implementing the tests as ZopeTestCase tests. I trust that you will be able to drop this into the correct folder and run.
________________________________________
= Comment - Entry #5 by esrever_otua on Sep 2, 2007 5:43 pm

Folks, I'm gobsmacked.

Fine, the testcase is a PloneTestCase - I will create a ZopeTestCase when I have a spare moment. Honestly, though, this is a trivial problem to duplicate. Upload a big file TTW, then try to run some code that pickles it.

Have either of you *actually run* the attached testcase? Does it fail? Can you offer some *constructive input* into why it is perfectly acceptable that it should fail?

tseaver:
You are using Zope 2.10 - the bug is logged against Zope 2.8 and Zope 2.9 - maybe it's fixed in 2.10, who knows? Also, you have dumped the data without using the Pickler class - maybe this affects it?
________________________________________
= Comment - Entry #4 by ajung on Sep 2, 2007 1:27 pm

I also have some doubts. We're storing large objects up to 150MB using Pdata chunking within the ZODB...never had any issues so far.


________________________________________
= Comment - Entry #3 by tseaver on Sep 2, 2007 7:19 am

I can't reproduce the described behavior at all, using the Python
API of File::

    $ cd ~/projects/Zope-CVS/Zope-2.10-branch
    $ PYTHONPATH=lib/python ../bin/python
    Python 2.4.4 (#1, Apr 30 2007, 11:13:06) 
    [GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> x = 'X' * 1024 * 1024
    >>> data = open('/tmp/issue_2306', 'wb')
    >>> for i in range(34):
    ...     data.write(x)
    ... 
    >>> data.flush()
    >>> data.close()
    >>> data = open('/tmp/issue_2306', 'rb')
    >>> from OFS.Image import File
    >>> f = File('issue_2306', '', '')
    >>> f.manage_upload(data)
    >>> f.size
    35651584L
    >>> from cPickle import dump, load
    >>> target = open('/tmp/pickle', 'wb')
    >>> dump(f, target)
    >>> target.flush()
    >>> target.close()
    >>> source = open('/tmp/pickle', 'rb')
    >>> f2 = load(source)
    >>> f2 == f
    False
    >>> f2.data == f.data
    False
    >>> f2.size
    35651584L
    >>> str(f2.data) == str(f.data)
    True


________________________________________
= Comment - Entry #2 by ajung on Sep 1, 2007 5:05 am

Please submit a *simple* testcase on top of ZopeTestCase but not on top of PloneTestCase with lots of different dependencies from other products.
________________________________________
= Request - Entry #1 by esrever_otua on Apr 5, 2007 6:19 am


Uploaded:  "pdata_failing_testcase.tar.gz"
 - http://www.zope.org/Collectors/Zope/2306/pdata_failing_testcase.tar.gz/view
In OFS.Image there is a 'File' class and 'Pdata' wrapper class. Pdata objects are designed to operate efficiently with large amounts of data by allowing themselves to be chained together in a C linked-list, while presenting an interface as if to a single object at the head of the list.
The 'File' class (which is used for, EG, ATFile, CMFFile, etc) stores its data internally in a Pdata object. It provides a 'manage_upload()' interface for modifying or supplying data to be stored in the File. This function splits the data into 64KB chunks and assigns each chunk to a new Pdata object in the C linked-list Pdata chain.
Once a file more than 32MB has been stored via manage_upload(), the File object can no longer be dumped with the Pickler() class.
EG, cPickle.Pickler.dump(OFS.Image.File) fails when the data stored in OFS.Image.File is greater than 32MB and was stored via the supplied manage_upload() interface.
The error is a RuntimeError for maximum recursion being hit.

Attached is a simple ZopeTestCase that demonstrates the problem. 
==============================================================



More information about the Zope-Collector-Monitor mailing list