I find that when I refresh my product it destroys some of the containment relationships. Things start failing, and as far as I can tell the only recovery is to completely rebuild the object.
This is a big problem, and if anyone could explain what is going on and how to avoid it I would appreciate it.
Here is the result of aq_chain before the refresh: [<RankQuestion instance at 8dd5620>, <OriginalSuborder instance at 8c9f8d8>, <EMailBallot instance at 8dfc870>, <__FactoryDispatcher__ instance at 8e73770>, <ProductDispatcher instance at 83f0618>, <Folder instance at 8d5733
and after [<RankQuestion instance at 8dee2d0>]
Interestingly, and object inside this retained some context: Before: [<RandomSuborder instance at 8df6248>, <RankQuestion instance at 8dd5620>, <OriginalSuborder instance at 8c9f8d8>, <EMailBallot instance at 8dfc870>, <__FactoryDispatcher__ instance at 8e73770>, <ProductDispatcher instance at 83f0618>, <Folder instance at 8d57330>, <Application instance at 8e44ae0>, <RequestContainer instance at 8ed53e8>]
After: [<RandomSuborder instance at 8be7128>, <RankQuestion instance at 8dee2d0>]
Notice that the new RandomSuborder instance (new, judging by the address, though it should be the same object) points to the new RankQuestion. Unfortunately, I need to go a little further than that to get the variable I'm looking for :(.
It may be relevant that I am explicitly wrapping objects uses a.__of__(b). I did this because I thought things weren't being wrapped at all, but the results above show the problem is different: the wrappers are lost on refresh. The refresh changes nothing structural, just some method code.
One thought that occurred to me is that it is not the changes to my product classes that is causing the trouble, but the inclusion of some of the items higher up the chain.
Ross Boylan wrote:
I find that when I refresh my product it destroys some of the containment relationships. Things start failing, and as far as I can tell the only recovery is to completely rebuild the object.
This is a big problem, and if anyone could explain what is going on and how to avoid it I would appreciate it.
Here is the result of aq_chain before the refresh: [<RankQuestion instance at 8dd5620>, <OriginalSuborder instance at 8c9f8d8>, <EMailBallot instance at 8dfc870>, <__FactoryDispatcher__ instance at 8e73770>, <ProductDispatcher instance at 83f0618>, <Folder instance at 8d5733
and after [<RankQuestion instance at 8dee2d0>]
[...]
Hmm, while what you're referring to is "refresh" in the sense of a product reload, it's important to first state that *no* acquisition is expected to survive between transactions.
Each transaction must separately acquire its objects; if you try to pass wrapped objects between transactions or threads you're going to end up in trouble.
Secondly, when a product is refreshed, the extensionclass module will probably create new base classes for any ExtensionClass derived class file. I dont *think* you can get much mileage out of knowing the id (address) of a class now, but be aware that a refresh will likely cause that address to change. I have seen some bizarre errors where module "constants" changed because of a reload, and "is" tests broke because "is" tests the object address.
None of this is explicitly what you're asking about -- but I think what you're trying to do is in violation of the "no wrapped objects should be stored past a transaction boundary" rule.
However, I may be misreading your question too -- which is why I mention those two rules above so YOU can see if they make sense in your context.
Matthew T. Kromer matt@zope.com wrote:
Hmm, while what you're referring to is "refresh" in the sense of a product reload, it's important to first state that *no* acquisition is expected to survive between transactions.
But subtransactions are ok, no? get_transaction().commit() is alright?
Florent
On Wed, Jul 24, 2002 at 10:38:44AM -0400, Matthew T. Kromer wrote:
Ross Boylan wrote:
I find that when I refresh my product it destroys some of the containment relationships. Things start failing, and as far as I can tell the only recovery is to completely rebuild the object.
This is a big problem, and if anyone could explain what is going on and how to avoid it I would appreciate it.
Here is the result of aq_chain before the refresh: [<RankQuestion instance at 8dd5620>, <OriginalSuborder instance at 8c9f8d8>, <EMailBallot instance at 8dfc870>, <__FactoryDispatcher__ instance at 8e73770>, <ProductDispatcher instance at 83f0618>, <Folder instance at 8d5733
and after [<RankQuestion instance at 8dee2d0>]
[...]
Hmm, while what you're referring to is "refresh" in the sense of a product reload, it's important to first state that *no* acquisition is expected to survive between transactions.
Each transaction must separately acquire its objects; if you try to pass wrapped objects between transactions or threads you're going to end up in trouble.
Secondly, when a product is refreshed, the extensionclass module will probably create new base classes for any ExtensionClass derived class file. I dont *think* you can get much mileage out of knowing the id (address) of a class now, but be aware that a refresh will likely cause that address to change. I have seen some bizarre errors where module "constants" changed because of a reload, and "is" tests broke because "is" tests the object address.
None of this is explicitly what you're asking about -- but I think what you're trying to do is in violation of the "no wrapped objects should be stored past a transaction boundary" rule.
However, I may be misreading your question too -- which is why I mention those two rules above so YOU can see if they make sense in your context.
The first point is definitely relevant, and explains why I am having problems. It's surprising what I'm doing is workign at all! The class redefinition in the second point might explain some of the timing of the problems, but it's the instances, not the classes that I am interested in.
The acquisition I want to do is in the object containment hierarchy, but URL of the request will also have this hieararchy. Is there some way I can grab it at the appropriate time?
Your comments also clarify a point that was unclear to me from the documentation on acquisition. The documents refers to the object containment hierarchy and the request path hierarchy, and recommend keeping them consistent. But I didn't understand which hierarchy it used if they weren't. Apparently only the request path matters.
It may be helpful to say more about the exact relations in my case: [indentation indicates containment in this diagram; capital letters are for objects] B ballot Q1 question R1a response R1b response SR suborder of responses see below for suborders R1a R1b (same objects as the R1's above) Q2 question ... NQ "namestyle" of questions (determines labeling) NR namestyle of responses SQ suborder of questions (sequential, random, ...) this suborder contains a list of the same questions Q1, Q2, etc that the ballot B holds. It also the name of the namestyle, to be acquired from the container. Generally, B and maybe Q will be in my request path, and the other items are not.
I ask the suborders for list of items, so they give me back a list of Q's or R's. The items in those lists were the ones I was trying to wrap.
At the most extreme case, I get a response R from the suborder list of a question Q, and I get the Q from the suborder of the ballot. So I't two levels removed from my original context, the ballot B, that has the namestyle I'm trying to acquire. The suborder on the Question needs to acquire the namestyle from the Ballot.
Finally, I may be making an overly conservative assumption about ObjectManagers. Without it, the suborders would not need to hold onto object references. It's easiest to explain this with a specific example. I want to be able to recover the original order questions were entered into the ballot. Ballot is a subclass of ObjectManager. I believe I am not allowed to make any assumptions about the order its items will be returned by objectItems(), so I am using the suborder to track that.
P.S. I also assume that objectItems('type') gets only objects of that type, not subtypes. Does anyone know if that's so?