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

Does not work on 5.1 #19

Open
csanahuja opened this issue Jul 13, 2018 · 3 comments
Open

Does not work on 5.1 #19

csanahuja opened this issue Jul 13, 2018 · 3 comments

Comments

@csanahuja
Copy link

csanahuja commented Jul 13, 2018

With new ClientStorage that Plone 5.1 uses sauna.reload no longer works and fails when trying to start the client with a RELOAD_PATH

Traceback (most recent call last):
  File "/opt/Plone-5.1/zeocluster/parts/client3/bin/interpreter", line 324, in <module>
    exec(compile(__file__f.read(), __file__, "exec"))
  File "/opt/Plone-5.1/buildout-cache/eggs/Zope2-2.13.26-py2.7.egg/Zope2/Startup/run.py", line 76, in <module>
    run()
  File "/opt/Plone-5.1/buildout-cache/eggs/Zope2-2.13.26-py2.7.egg/Zope2/Startup/run.py", line 22, in run
    starter.prepare()
  File "/opt/Plone-5.1/buildout-cache/eggs/Zope2-2.13.26-py2.7.egg/Zope2/Startup/__init__.py", line 102, in prepare
    self.sendEvents()
  File "/opt/Plone-5.1/buildout-cache/eggs/Zope2-2.13.26-py2.7.egg/Zope2/Startup/__init__.py", line 75, in sendEvents
    notify(ProcessStarting())
  File "/opt/Plone-5.1/buildout-cache/eggs/zope.event-3.5.2-py2.7.egg/zope/event/__init__.py", line 31, in notify
    subscriber(event)
  File "/opt/Plone-5.1/buildout-cache/eggs/zope.component-4.4.1-py2.7.egg/zope/component/event.py", line 27, in dispatch
    component_subscribers(event, None)
  File "/opt/Plone-5.1/buildout-cache/eggs/zope.component-4.4.1-py2.7.egg/zope/component/_api.py", line 139, in subscribers
    return sitemanager.subscribers(objects, interface)
  File "/opt/Plone-5.1/buildout-cache/eggs/zope.interface-4.4.3-py2.7-linux-x86_64.egg/zope/interface/registry.py", line 442, in subscribers
    return self.adapters.subscribers(objects, provided)
  File "/opt/Plone-5.1/buildout-cache/eggs/zope.interface-4.4.3-py2.7-linux-x86_64.egg/zope/interface/adapter.py", line 607, in subscribers
    subscription(*objects)
  File "/opt/Plone-5.1/buildout-cache/eggs/sauna.reload-0.5.5-py2.7.egg/sauna/reload/eventhandlers.py", line 69, in startForkLoop
    forkloop.start()
  File "/opt/Plone-5.1/buildout-cache/eggs/sauna.reload-0.5.5-py2.7.egg/sauna/reload/forkloop.py", line 94, in start
    self.database = IDatabaseHooks(DB)
  File "/opt/Plone-5.1/buildout-cache/eggs/zope.component-4.4.1-py2.7.egg/zope/component/hookable.py", line 33, in __call__
    return self.__implementation(*args, **kw)
  File "/opt/Plone-5.1/buildout-cache/eggs/zope.component-4.4.1-py2.7.egg/zope/component/hooks.py", line 119, in adapter_hook
    return siteinfo.adapter_hook(interface, object, name, default)
  File "/opt/Plone-5.1/buildout-cache/eggs/sauna.reload-0.5.5-py2.7.egg/sauna/reload/adapters.py", line 38, in __init__
    self.context = IDatabaseHooks(context.storage)
  File "/opt/Plone-5.1/buildout-cache/eggs/zope.component-4.4.1-py2.7.egg/zope/component/hookable.py", line 33, in __call__
    return self.__implementation(*args, **kw)
  File "/opt/Plone-5.1/buildout-cache/eggs/zope.component-4.4.1-py2.7.egg/zope/component/hooks.py", line 119, in adapter_hook
    return siteinfo.adapter_hook(interface, object, name, default)
  File "/opt/Plone-5.1/buildout-cache/eggs/sauna.reload-0.5.5-py2.7.egg/sauna/reload/adapters.py", line 111, in __init__
    _rpc_mgr = self.context._rpc_mgr
AttributeError: 'ClientStorage' object has no attribute '_rpc_mgr'

I have seen than ClientStorage has changed some things, like attributes names and way to open a new connection and cache.

Without really understanding the underlying changes I have tried to change the adapters.py file to do it the new way and aparently it is working but I do not know if it will have side effects or will work like before, just tested a small change in a browser view method and it was reloaded.

Just in case it helps I will copy the changes I made in adapters.py

from ZEO.cache import ClientCache
from ZEO.asyncio.client import ClientThread
import ZEO.asyncio.client

class ZEOClientStorageDatabaseHooksAdapter(object):
    """
    ZEO-client adapter
    """
    implements(IDatabaseHooks)
    adapts(ClientStorage)

    def __init__(self, context):
        self.context = context

        # Store cache settings
        self._cache_path = self.context._cache.path
        self._cache_size = self.context._cache.maxsize

        # Close the main process' connection (before forkloop)
        _server = self.context._server
        _server.close()

        # Close the main process' cache (before forkloop)
        self.context._cache.close()

    def prepareForReload(self):
        _server = self.context._server
        if self.context.is_connected():
            # Close the connection (before the child is killed)
            _server.close()

            # Close the cache (before the child is killed)
            self.context._cache.close()

    def resumeFromReload(self):
        # Open a new cache for the new child
        self.context._cache = ClientCache(
            self._cache_path, size=self._cache_size)

        # Prepare a new connection for the new child
        self.context._server = ClientThread(
            self.context._addr, 
            self.context, 
            self.context._cache, 
            self.context._storage, 
            ZEO.asyncio.client.Fallback if self.context._read_only_fallback else self.context._is_read_only,
            None,
            ssl = None, 
            ssl_server_hostname = None,
            credentials=None)

        self.context._call = self.context._server.call
        self.context._async = self.context._server.async
        self.context._async_iter = self.context._server.async_iter
        self.context._wait = self.context._server.wait

        # Connect the new child to ZEO
        wait = True
        if wait:
            try:
                self.context._wait()
            except Exception:
                # No point in keeping the server going of the storage
                # creation fails
                self.context._server.close()
                raise

@djowett
Copy link

djowett commented Jan 19, 2019

I had the same error - but the above fix, whilst stopping the error,
doesn't seem to fix automatic reloads on a code change (dexterity schemas at least).

I've since found that plone.reload seems to work on 5.1

@datakurre
Copy link

Plone 5.1 final and later have new generation of ZODB, so I'm not surprised of issues myself. Unfortunately, I've been mostly working with a bit older versions, so I have not been able to see and fix these issues myself yet.

This will be fixed eventually, but meanwhile, going back to plone.reload is a good choice. Many years ago, sauna.reload was required, because plone.reload could only reload ZCML registered components and unable to reload components configured with Grok. Now that Dexterity development no longer involves any Grok, sauna.reload is not really needed.

That said, we are using venusianconfiguration a lot in in-house packages and therefore need to fix sauna.reload once we hit this issue.

@datakurre
Copy link

I'm expecting to work on this this year to add support for Python 3 and Plone 5.2, because I still need this with venusianconfiguration.

That said, I also assume that all ZCML products are better developed with plone.reload, which can reload them just fine (and Grok should not be an issue, because it does not support Python 3).

datakurre added a commit that referenced this issue May 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants