| Index: third_party/logilab/common/pyro_ext.py
|
| diff --git a/third_party/logilab/common/pyro_ext.py b/third_party/logilab/common/pyro_ext.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..0f4d2790b51e44023c79735d6c036a92806a7e10
|
| --- /dev/null
|
| +++ b/third_party/logilab/common/pyro_ext.py
|
| @@ -0,0 +1,180 @@
|
| +# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
|
| +# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
|
| +#
|
| +# This file is part of logilab-common.
|
| +#
|
| +# logilab-common is free software: you can redistribute it and/or modify it under
|
| +# the terms of the GNU Lesser General Public License as published by the Free
|
| +# Software Foundation, either version 2.1 of the License, or (at your option) any
|
| +# later version.
|
| +#
|
| +# logilab-common is distributed in the hope that it will be useful, but WITHOUT
|
| +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
| +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
| +# details.
|
| +#
|
| +# You should have received a copy of the GNU Lesser General Public License along
|
| +# with logilab-common. If not, see <http://www.gnu.org/licenses/>.
|
| +"""Python Remote Object utilities
|
| +
|
| +Main functions available:
|
| +
|
| +* `register_object` to expose arbitrary object through pyro using delegation
|
| + approach and register it in the nameserver.
|
| +* `ns_unregister` unregister an object identifier from the nameserver.
|
| +* `ns_get_proxy` get a pyro proxy from a nameserver object identifier.
|
| +"""
|
| +
|
| +__docformat__ = "restructuredtext en"
|
| +
|
| +import logging
|
| +import tempfile
|
| +
|
| +from Pyro import core, naming, errors, util, config
|
| +
|
| +_LOGGER = logging.getLogger('pyro')
|
| +_MARKER = object()
|
| +
|
| +config.PYRO_STORAGE = tempfile.gettempdir()
|
| +
|
| +def ns_group_and_id(idstr, defaultnsgroup=_MARKER):
|
| + try:
|
| + nsgroup, nsid = idstr.rsplit('.', 1)
|
| + except ValueError:
|
| + if defaultnsgroup is _MARKER:
|
| + nsgroup = config.PYRO_NS_DEFAULTGROUP
|
| + else:
|
| + nsgroup = defaultnsgroup
|
| + nsid = idstr
|
| + if nsgroup is not None and not nsgroup.startswith(':'):
|
| + nsgroup = ':' + nsgroup
|
| + return nsgroup, nsid
|
| +
|
| +def host_and_port(hoststr):
|
| + if not hoststr:
|
| + return None, None
|
| + try:
|
| + hoststr, port = hoststr.split(':')
|
| + except ValueError:
|
| + port = None
|
| + else:
|
| + port = int(port)
|
| + return hoststr, port
|
| +
|
| +_DAEMONS = {}
|
| +_PYRO_OBJS = {}
|
| +def _get_daemon(daemonhost, start=True):
|
| + if not daemonhost in _DAEMONS:
|
| + if not start:
|
| + raise Exception('no daemon for %s' % daemonhost)
|
| + if not _DAEMONS:
|
| + core.initServer(banner=0)
|
| + host, port = host_and_port(daemonhost)
|
| + daemon = core.Daemon(host=host, port=port)
|
| + _DAEMONS[daemonhost] = daemon
|
| + return _DAEMONS[daemonhost]
|
| +
|
| +
|
| +def locate_ns(nshost):
|
| + """locate and return the pyro name server to the daemon"""
|
| + core.initClient(banner=False)
|
| + return naming.NameServerLocator().getNS(*host_and_port(nshost))
|
| +
|
| +
|
| +def register_object(object, nsid, defaultnsgroup=_MARKER,
|
| + daemonhost=None, nshost=None, use_pyrons=True):
|
| + """expose the object as a pyro object and register it in the name-server
|
| +
|
| + if use_pyrons is False, then the object is exposed, but no
|
| + attempt to register it to a pyro nameserver is made.
|
| +
|
| + return the pyro daemon object
|
| + """
|
| + nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup)
|
| + daemon = _get_daemon(daemonhost)
|
| + if use_pyrons:
|
| + nsd = locate_ns(nshost)
|
| + # make sure our namespace group exists
|
| + try:
|
| + nsd.createGroup(nsgroup)
|
| + except errors.NamingError:
|
| + pass
|
| + daemon.useNameServer(nsd)
|
| + # use Delegation approach
|
| + impl = core.ObjBase()
|
| + impl.delegateTo(object)
|
| + qnsid = '%s.%s' % (nsgroup, nsid)
|
| + uri = daemon.connect(impl, qnsid)
|
| + _PYRO_OBJS[qnsid] = str(uri)
|
| + _LOGGER.info('registered %s a pyro object using group %s and id %s',
|
| + object, nsgroup, nsid)
|
| + return daemon
|
| +
|
| +def get_object_uri(qnsid):
|
| + return _PYRO_OBJS[qnsid]
|
| +
|
| +def ns_unregister(nsid, defaultnsgroup=_MARKER, nshost=None):
|
| + """unregister the object with the given nsid from the pyro name server"""
|
| + nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup)
|
| + try:
|
| + nsd = locate_ns(nshost)
|
| + except errors.PyroError, ex:
|
| + # name server not responding
|
| + _LOGGER.error('can\'t locate pyro name server: %s', ex)
|
| + else:
|
| + try:
|
| + nsd.unregister('%s.%s' % (nsgroup, nsid))
|
| + _LOGGER.info('%s unregistered from pyro name server', nsid)
|
| + except errors.NamingError:
|
| + _LOGGER.warning('%s not registered in pyro name server', nsid)
|
| +
|
| +
|
| +def ns_reregister(nsid, defaultnsgroup=_MARKER, nshost=None):
|
| + """reregister a pyro object into the name server. You only have to specify
|
| + the name-server id of the object (though you MUST have gone through
|
| + `register_object` for the given object previously).
|
| +
|
| + This is especially useful for long running server while the name server may
|
| + have been restarted, and its records lost.
|
| + """
|
| + nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup)
|
| + qnsid = '%s.%s' % (nsgroup, nsid)
|
| + nsd = locate_ns(nshost)
|
| + try:
|
| + nsd.unregister(qnsid)
|
| + except errors.NamingError:
|
| + # make sure our namespace group exists
|
| + try:
|
| + nsd.createGroup(nsgroup)
|
| + except errors.NamingError:
|
| + pass
|
| + nsd.register(qnsid, _PYRO_OBJS[qnsid])
|
| +
|
| +def ns_get_proxy(nsid, defaultnsgroup=_MARKER, nshost=None):
|
| + """
|
| + if nshost is None, the nameserver is found by a broadcast.
|
| + """
|
| + # resolve the Pyro object
|
| + nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup)
|
| + try:
|
| + nsd = locate_ns(nshost)
|
| + pyrouri = nsd.resolve('%s.%s' % (nsgroup, nsid))
|
| + except errors.ProtocolError, ex:
|
| + raise errors.PyroError(
|
| + 'Could not connect to the Pyro name server (host: %s)' % nshost)
|
| + except errors.NamingError:
|
| + raise errors.PyroError(
|
| + 'Could not get proxy for %s (not registered in Pyro), '
|
| + 'you may have to restart your server-side application' % nsid)
|
| + return core.getProxyForURI(pyrouri)
|
| +
|
| +def get_proxy(pyro_uri):
|
| + """get a proxy for the passed pyro uri without using a nameserver
|
| + """
|
| + return core.getProxyForURI(pyro_uri)
|
| +
|
| +def set_pyro_log_threshold(level):
|
| + pyrologger = logging.getLogger('Pyro.%s' % str(id(util.Log)))
|
| + # remove handlers so only the root handler is used
|
| + pyrologger.handlers = []
|
| + pyrologger.setLevel(level)
|
|
|