OLD | NEW |
(Empty) | |
| 1 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
| 2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
| 3 # |
| 4 # This file is part of logilab-common. |
| 5 # |
| 6 # logilab-common is free software: you can redistribute it and/or modify it unde
r |
| 7 # the terms of the GNU Lesser General Public License as published by the Free |
| 8 # Software Foundation, either version 2.1 of the License, or (at your option) an
y |
| 9 # later version. |
| 10 # |
| 11 # logilab-common is distributed in the hope that it will be useful, but WITHOUT |
| 12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| 13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
| 14 # details. |
| 15 # |
| 16 # You should have received a copy of the GNU Lesser General Public License along |
| 17 # with logilab-common. If not, see <http://www.gnu.org/licenses/>. |
| 18 """Python Remote Object utilities |
| 19 |
| 20 Main functions available: |
| 21 |
| 22 * `register_object` to expose arbitrary object through pyro using delegation |
| 23 approach and register it in the nameserver. |
| 24 * `ns_unregister` unregister an object identifier from the nameserver. |
| 25 * `ns_get_proxy` get a pyro proxy from a nameserver object identifier. |
| 26 """ |
| 27 |
| 28 __docformat__ = "restructuredtext en" |
| 29 |
| 30 import logging |
| 31 import tempfile |
| 32 |
| 33 from Pyro import core, naming, errors, util, config |
| 34 |
| 35 _LOGGER = logging.getLogger('pyro') |
| 36 _MARKER = object() |
| 37 |
| 38 config.PYRO_STORAGE = tempfile.gettempdir() |
| 39 |
| 40 def ns_group_and_id(idstr, defaultnsgroup=_MARKER): |
| 41 try: |
| 42 nsgroup, nsid = idstr.rsplit('.', 1) |
| 43 except ValueError: |
| 44 if defaultnsgroup is _MARKER: |
| 45 nsgroup = config.PYRO_NS_DEFAULTGROUP |
| 46 else: |
| 47 nsgroup = defaultnsgroup |
| 48 nsid = idstr |
| 49 if nsgroup is not None and not nsgroup.startswith(':'): |
| 50 nsgroup = ':' + nsgroup |
| 51 return nsgroup, nsid |
| 52 |
| 53 def host_and_port(hoststr): |
| 54 if not hoststr: |
| 55 return None, None |
| 56 try: |
| 57 hoststr, port = hoststr.split(':') |
| 58 except ValueError: |
| 59 port = None |
| 60 else: |
| 61 port = int(port) |
| 62 return hoststr, port |
| 63 |
| 64 _DAEMONS = {} |
| 65 _PYRO_OBJS = {} |
| 66 def _get_daemon(daemonhost, start=True): |
| 67 if not daemonhost in _DAEMONS: |
| 68 if not start: |
| 69 raise Exception('no daemon for %s' % daemonhost) |
| 70 if not _DAEMONS: |
| 71 core.initServer(banner=0) |
| 72 host, port = host_and_port(daemonhost) |
| 73 daemon = core.Daemon(host=host, port=port) |
| 74 _DAEMONS[daemonhost] = daemon |
| 75 return _DAEMONS[daemonhost] |
| 76 |
| 77 |
| 78 def locate_ns(nshost): |
| 79 """locate and return the pyro name server to the daemon""" |
| 80 core.initClient(banner=False) |
| 81 return naming.NameServerLocator().getNS(*host_and_port(nshost)) |
| 82 |
| 83 |
| 84 def register_object(object, nsid, defaultnsgroup=_MARKER, |
| 85 daemonhost=None, nshost=None, use_pyrons=True): |
| 86 """expose the object as a pyro object and register it in the name-server |
| 87 |
| 88 if use_pyrons is False, then the object is exposed, but no |
| 89 attempt to register it to a pyro nameserver is made. |
| 90 |
| 91 return the pyro daemon object |
| 92 """ |
| 93 nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup) |
| 94 daemon = _get_daemon(daemonhost) |
| 95 if use_pyrons: |
| 96 nsd = locate_ns(nshost) |
| 97 # make sure our namespace group exists |
| 98 try: |
| 99 nsd.createGroup(nsgroup) |
| 100 except errors.NamingError: |
| 101 pass |
| 102 daemon.useNameServer(nsd) |
| 103 # use Delegation approach |
| 104 impl = core.ObjBase() |
| 105 impl.delegateTo(object) |
| 106 qnsid = '%s.%s' % (nsgroup, nsid) |
| 107 uri = daemon.connect(impl, qnsid) |
| 108 _PYRO_OBJS[qnsid] = str(uri) |
| 109 _LOGGER.info('registered %s a pyro object using group %s and id %s', |
| 110 object, nsgroup, nsid) |
| 111 return daemon |
| 112 |
| 113 def get_object_uri(qnsid): |
| 114 return _PYRO_OBJS[qnsid] |
| 115 |
| 116 def ns_unregister(nsid, defaultnsgroup=_MARKER, nshost=None): |
| 117 """unregister the object with the given nsid from the pyro name server""" |
| 118 nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup) |
| 119 try: |
| 120 nsd = locate_ns(nshost) |
| 121 except errors.PyroError, ex: |
| 122 # name server not responding |
| 123 _LOGGER.error('can\'t locate pyro name server: %s', ex) |
| 124 else: |
| 125 try: |
| 126 nsd.unregister('%s.%s' % (nsgroup, nsid)) |
| 127 _LOGGER.info('%s unregistered from pyro name server', nsid) |
| 128 except errors.NamingError: |
| 129 _LOGGER.warning('%s not registered in pyro name server', nsid) |
| 130 |
| 131 |
| 132 def ns_reregister(nsid, defaultnsgroup=_MARKER, nshost=None): |
| 133 """reregister a pyro object into the name server. You only have to specify |
| 134 the name-server id of the object (though you MUST have gone through |
| 135 `register_object` for the given object previously). |
| 136 |
| 137 This is especially useful for long running server while the name server may |
| 138 have been restarted, and its records lost. |
| 139 """ |
| 140 nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup) |
| 141 qnsid = '%s.%s' % (nsgroup, nsid) |
| 142 nsd = locate_ns(nshost) |
| 143 try: |
| 144 nsd.unregister(qnsid) |
| 145 except errors.NamingError: |
| 146 # make sure our namespace group exists |
| 147 try: |
| 148 nsd.createGroup(nsgroup) |
| 149 except errors.NamingError: |
| 150 pass |
| 151 nsd.register(qnsid, _PYRO_OBJS[qnsid]) |
| 152 |
| 153 def ns_get_proxy(nsid, defaultnsgroup=_MARKER, nshost=None): |
| 154 """ |
| 155 if nshost is None, the nameserver is found by a broadcast. |
| 156 """ |
| 157 # resolve the Pyro object |
| 158 nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup) |
| 159 try: |
| 160 nsd = locate_ns(nshost) |
| 161 pyrouri = nsd.resolve('%s.%s' % (nsgroup, nsid)) |
| 162 except errors.ProtocolError, ex: |
| 163 raise errors.PyroError( |
| 164 'Could not connect to the Pyro name server (host: %s)' % nshost) |
| 165 except errors.NamingError: |
| 166 raise errors.PyroError( |
| 167 'Could not get proxy for %s (not registered in Pyro), ' |
| 168 'you may have to restart your server-side application' % nsid) |
| 169 return core.getProxyForURI(pyrouri) |
| 170 |
| 171 def get_proxy(pyro_uri): |
| 172 """get a proxy for the passed pyro uri without using a nameserver |
| 173 """ |
| 174 return core.getProxyForURI(pyro_uri) |
| 175 |
| 176 def set_pyro_log_threshold(level): |
| 177 pyrologger = logging.getLogger('Pyro.%s' % str(id(util.Log))) |
| 178 # remove handlers so only the root handler is used |
| 179 pyrologger.handlers = [] |
| 180 pyrologger.setLevel(level) |
OLD | NEW |