zodb / relstorage

A backend for ZODB that stores pickles in a relational database.
Other
54 stars 46 forks source link

Crash with persistent site managers in relstorage 3.2 #411

Closed sjustas closed 3 years ago

sjustas commented 4 years ago

Hi,

I'm trying to upgrade relstorage[postgresql] from 2.1.1 to 3.2.0.

I have a site with a persistent zope.site.site.LocalSiteManager. When the new site is set with zope.component.hooks.setSite(site) (from zope.site.site.threadSiteSubscriber), it's registry has not been loaded yet:

>>> zope.component.hooks.getSite().getSiteManager().adapters._p_state
-1

Later, when a subscriber lookup triggers the registry load, it crashes, because relstorage is trying to look up ITypedParams in the registry it is currently trying to load (see traceback below).

If I monkey-patch zope.compinent.hooks.setSite to hooks.removeSecurityProxy(site).getSiteManager().adapters._p_activate() when setting the site, it works of course, but it doesn't look like the nicest way to solve this.

Do you have any insigths? Thanks!

(notice self.ro = ro.ro(self) still being built in the traceback and a verifying adapter already trying to use it)

Traceback (most recent call last):
  File ".../ve/lib/python3.7/site-packages/zope/publisher/publish.py", line 141, in publish
    obj = request.traverse(obj)
  File ".../ve/lib/python3.7/site-packages/zope/publisher/browser.py", line 575, in traverse
    ob = super(BrowserRequest, self).traverse(obj)
  File ".../ve/lib/python3.7/site-packages/zope/publisher/http.py", line 511, in traverse
    ob = super(HTTPRequest, self).traverse(obj)
  File ".../ve/lib/python3.7/site-packages/zope/publisher/base.py", line 249, in traverse
    publication.callTraversalHooks(self, obj)
  File ".../ve/lib/python3.7/site-packages/zope/app/publication/zopepublication.py", line 134, in callTraversalHooks
    notify(BeforeTraverseEvent(ob, request))
  File ".../ve/lib/python3.7/site-packages/zope/event/__init__.py", line 32, in notify
    subscriber(event)
  File ".../ve/lib/python3.7/site-packages/zope/component/event.py", line 27, in dispatch
    component_subscribers(event, None)
  File ".../ve/lib/python3.7/site-packages/zope/component/_api.py", line 124, in subscribers
    return sitemanager.subscribers(objects, interface)
  File ".../ve/lib/python3.7/site-packages/zope/interface/registry.py", line 442, in subscribers
    return self.adapters.subscribers(objects, provided)
  File ".../ve/lib/python3.7/site-packages/zope/interface/adapter.py", line 612, in subscribers
    subscription(*objects)
  File ".../src/app/auth.py", line 614, in addPrincipalBeforeTraversal
    zope.event.notify(PrincipalAddedEvent(event.object, event.request))
  File ".../ve/lib/python3.7/site-packages/zope/event/__init__.py", line 32, in notify
    subscriber(event)
  File ".../ve/lib/python3.7/site-packages/zope/component/event.py", line 27, in dispatch
    component_subscribers(event, None)
  File ".../ve/lib/python3.7/site-packages/zope/component/_api.py", line 124, in subscribers
    return sitemanager.subscribers(objects, interface)
  File ".../ve/lib/python3.7/site-packages/zope/interface/registry.py", line 442, in subscribers
    return self.adapters.subscribers(objects, provided)
  File ".../ve/lib/python3.7/site-packages/ZODB/Connection.py", line 795, in setstate
    self._reader.setGhostState(obj, p)
  File ".../ve/lib/python3.7/site-packages/ZODB/serialize.py", line 634, in setGhostState
    obj.__setstate__(state)
  File ".../ve/lib/python3.7/site-packages/zope/component/persistentregistry.py", line 42, in __setstate__
    self.__bases__ = bases
  File ".../ve/lib/python3.7/site-packages/zope/interface/adapter.py", line 93, in <lambda>
    lambda self, bases: self._setBases(bases),
  File ".../ve/lib/python3.7/site-packages/zope/interface/adapter.py", line 89, in _setBases
    self.ro = ro.ro(self)
  File ".../ve/lib/python3.7/site-packages/zope/interface/ro.py", line 64, in ro
    return _mergeOrderings([_flatten(object)])
  File ".../ve/lib/python3.7/site-packages/zope/interface/ro.py", line 57, in _flatten
    result[i:i] = ob.__bases__
  File ".../ve/lib/python3.7/site-packages/ZODB/Connection.py", line 791, in setstate
    p, serial = self._storage.load(oid)
  File "src/perfmetrics/metric.py", line 66, in perfmetrics._metric._AbstractMetricImpl.__call__
  File ".../ve/lib/python3.7/site-packages/relstorage/storage/load.py", line 110, in load
    state, tid_int = self.__load_using_method(load_cursor, self.cache.load, oid_int)
  File ".../ve/lib/python3.7/site-packages/relstorage/storage/load.py", line 85, in __load_using_method
    return meth(load_cursor, argument)
  File ".../ve/lib/python3.7/site-packages/relstorage/cache/storage_cache.py", line 457, in load
    cursor, oid_int)
  File "src/perfmetrics/metric.py", line 66, in perfmetrics._metric._AbstractMetricImpl.__call__
  File ".../ve/lib/python3.7/site-packages/relstorage/adapters/mover.py", line 78, in load_current
    stmt = self._load_current_query
  File ".../ve/lib/python3.7/site-packages/relstorage/adapters/sql/query.py", line 115, in __get__
    result = self.bind(inst).compiled()
  File ".../ve/lib/python3.7/site-packages/relstorage/_util.py", line 391, in decorated
    v = cache[key] = func(instance)
  File ".../ve/lib/python3.7/site-packages/relstorage/adapters/sql/query.py", line 125, in compiled
    return CompiledQuery(self)
  File ".../ve/lib/python3.7/site-packages/relstorage/adapters/sql/query.py", line 162, in __init__
    self._prepare_stmt, self.stmt, self._prepare_converter = compiler.prepare()
  File ".../ve/lib/python3.7/site-packages/relstorage/adapters/sql/dialect.py", line 190, in prepare
    datatypes = self._find_datatypes_for_prepared_query()
  File ".../ve/lib/python3.7/site-packages/relstorage/adapters/sql/dialect.py", line 181, in _find_datatypes_for_prepared_query
    param_provider = ITypedParams(self.root, None)
  File ".../ve/lib/python3.7/site-packages/zope/component/hooks.py", line 134, in adapter_hook
    return siteinfo.adapter_hook(interface, object, name, default)
  File ".../ve/lib/python3.7/site-packages/zope/interface/adapter.py", line 466, in changed
    pass
AttributeError: '_LocalAdapterRegistry' object has no attribute 'ro'
jamadden commented 3 years ago

Thanks for the report. That looks like a bug in RelStorage.