Skip to content
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

cache semantics are wrong on PyPy #29

Closed
glyph opened this issue Jan 8, 2015 · 3 comments
Closed

cache semantics are wrong on PyPy #29

glyph opened this issue Jan 8, 2015 · 3 comments

Comments

@glyph
Copy link
Member

glyph commented Jan 8, 2015

I have not managed to reproduce this in isolation outside the context of twisted/imaginary#64 just yet, but I believe I'm seeing Item instances with the same storeID for the same store existing at the same time.

Superficially it appears that the weakref to an object returns None while there are still strong references held elsewhere in the program. I feel like I must be wrong about that though.

@glyph
Copy link
Member Author

glyph commented Jan 8, 2015

I believe the sequence of events is as follows.

Item A is loaded, with storeID=1. It goes into the FinalizingCache. Great, its identity is preserved, everyone is happy.

All strong references to A are lost. It is garbage collected. However, since PyPy defers execution of weakref callbacks, its entry remains in the cache.

Item A-prime is loaded, with storeID=1. It goes into the FinalizingCache. It properly notices that the weakref presently in the cache evaluates to None, so is dead, and replaces it. A-prime's identity is preserved, all is happy.

Now, PyPy sees fit to invoke A's weakref callback. It deletes 1 from the storeID cache.

Item A-prime-prime is now loaded, with storeID=1. Except some callers still have references to A-prime.

Everything goes downhill quickly from there.

mithrandi added a commit to mithrandi/axiom that referenced this issue Jan 8, 2015
@glyph glyph changed the title cache semantics are (probably?) wrong on PyPy cache semantics are wrong on PyPy Jan 8, 2015
@mithrandi
Copy link
Contributor

It may be possible to reproduce this issue on CPython. The sequence of events would require having a second weakref to an item, with a weakref callback that causes the item to be reloaded from the database, and for that weakref callback to run before the one in FinalizingCache runs.

However, this is a scenario that is unlikely to occur in user code, and I have not yet verified that the reproduction is actually possible.

@glyph
Copy link
Member Author

glyph commented Jan 9, 2015

In any case, I believe the fix would be right for that scenario too :).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants