-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
It's very easy to create reference cycles that require the GC to clean up #82
Comments
Jason Madden wrote at 2019-5-14 06:24 -0700:
As discussed in zopefoundation/ZODB#268 (comment), if, through any arbitrarily long chain of imports, a data manager implementation ultimately winds up importing the `transaction` module, then when it joins the default transaction there will be a reference cycle (the data manager will reference the `transaction` module through `__globals__`, which references the transaction manager, which references the transaction which references the data manager).
I'm not sure what, if anything, can be done about this, but if anybody has an idea, that'd be great.
The transaction could (and I think does normally) break its connection
to the data (aka resource) managers in a commit/abort - thus
breaking the cycle. I would expect also that a transaction
interacts with its transaction manager on commit/abort. This, too,
could be a place to break a potential cycle.
That reminds me that after a commit/abort, transaction hooks should
get cleared as well - as they might have references to a
data manager as well (even though, a data manager does not need
hooks to interact with the transaction).
|
That's an excellent point. But in this particular test case, the resource warning doesn't show up until the garbage collector runs, and it always shows up exactly when you run the collector, which (I think) means that there was a cycle involved:
There must be some other cycle... |
Looks like we had a bug here: |
Likely a feature (not a bug): not calling |
Feature or bug...the ResourceWanring issues should be somehow handled. It is not very helpful and not trustworthy for people running Zope or Plone in production with tons of such messages in the logs for standard operations. |
Specifically, synchronizers and its manager. And abort() always invokes _free() even in the case of exceptions. commit() still doesn't so that the synchronizers are available for the expected abort(). Fixes #82
I had a branch where I tested doing more cleanups (having I decided not to pursue that branch into a PR because (a) it didn't fix the problem and (b) there were some subtle semantic differences. Notably, in the I'd like to make a release of transaction 3.0 to get the new hook functionality out. If there are no objections I'll plan on doing that in a day or so. |
… little safer. Specifically, free the manager and synchronizers, plus a few other dictionaries that could be arbitrary size and contain arbitrary data. And abort() always invokes _free() even in the case of exceptions. commit() still doesn't so that the synchronizers are available for the expected abort(). But take care about when and how abort frees its manager: not only does this preserve backwards compatibility, but it lets it be safe to abort a transaction object more than once. A happy side-effect of only freeing the manager there is that synchronizers can access data they set in afterCompletion(). From discussion in #82
… little safer. Specifically, free the manager and synchronizers, plus a few other dictionaries that could be arbitrary size and contain arbitrary data. And abort() always invokes _free() even in the case of exceptions. commit() still doesn't so that the synchronizers are available for the expected abort(). But take care about when and how abort frees its manager: not only does this preserve backwards compatibility, but it lets it be safe to abort a transaction object more than once. A happy side-effect of only freeing the manager there is that synchronizers can access data they set in afterCompletion(). From discussion in #82
The error is still open in ZODB 5.7.0 (Plone 6.0.0a4) where I see this error frequently:
|
I have recently added a new feature to |
I just released https://pypi.org/project/zope.testrunner/5.5/ containing the changed @d-maurer mentioned. |
As discussed in zopefoundation/ZODB#268 (comment), if, through any arbitrarily long chain of imports, a data manager implementation ultimately winds up importing the
transaction
module, then when it joins the default transaction there will be a reference cycle (the data manager will reference thetransaction
module through__globals__
, which references the transaction manager, which references the transaction which references the data manager).I'm not sure what, if anything, can be done about this, but if anybody has an idea, that'd be great.
The text was updated successfully, but these errors were encountered: