Package logilab :: Package common :: Module pyro_ext
[frames] | no frames]

Source Code for Module logilab.common.pyro_ext

  1  # copyright 2003-2010 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 under 
  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) any 
  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):
86 """expose the object as a pyro object and register it in the name-server 87 88 return the pyro daemon object 89 """ 90 nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup) 91 daemon = _get_daemon(daemonhost) 92 nsd = locate_ns(nshost) 93 # make sure our namespace group exists 94 try: 95 nsd.createGroup(nsgroup) 96 except errors.NamingError: 97 pass 98 daemon.useNameServer(nsd) 99 # use Delegation approach 100 impl = core.ObjBase() 101 impl.delegateTo(object) 102 qnsid = '%s.%s' % (nsgroup, nsid) 103 uri = daemon.connect(impl, qnsid) 104 _PYRO_OBJS[qnsid] = uri 105 _LOGGER.info('registered %s a pyro object using group %s and id %s', 106 object, nsgroup, nsid) 107 return daemon
108 109
110 -def ns_unregister(nsid, defaultnsgroup=_MARKER, nshost=None):
111 """unregister the object with the given nsid from the pyro name server""" 112 nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup) 113 try: 114 nsd = locate_ns(nshost) 115 except errors.PyroError, ex: 116 # name server not responding 117 _LOGGER.error('can\'t locate pyro name server: %s', ex) 118 else: 119 try: 120 nsd.unregister('%s.%s' % (nsgroup, nsid)) 121 _LOGGER.info('%s unregistered from pyro name server', nsid) 122 except errors.NamingError: 123 _LOGGER.warning('%s not registered in pyro name server', nsid)
124
125 -def ns_reregister(nsid, defaultnsgroup=_MARKER, nshost=None):
126 """reregister a pyro object into the name server. You only have to specify 127 the name-server id of the object (though you MUST have gone through 128 `register_object` for the given object previously). 129 130 This is especially useful for long running server while the name server may 131 have been restarted, and its records lost. 132 """ 133 nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup) 134 qnsid = '%s.%s' % (nsgroup, nsid) 135 nsd = locate_ns(nshost) 136 try: 137 nsd.unregister(qnsid) 138 except errors.NamingError: 139 # make sure our namespace group exists 140 try: 141 nsd.createGroup(nsgroup) 142 except errors.NamingError: 143 pass 144 nsd.register(qnsid, _PYRO_OBJS[qnsid])
145
146 -def ns_get_proxy(nsid, defaultnsgroup=_MARKER, nshost=None):
147 nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup) 148 # resolve the Pyro object 149 try: 150 nsd = locate_ns(nshost) 151 pyrouri = nsd.resolve('%s.%s' % (nsgroup, nsid)) 152 except errors.ProtocolError, ex: 153 raise errors.PyroError( 154 'Could not connect to the Pyro name server (host: %s)' % nshost) 155 except errors.NamingError: 156 raise errors.PyroError( 157 'Could not get proxy for %s (not registered in Pyro), ' 158 'you may have to restart your server-side application' % nsid) 159 return core.getProxyForURI(pyrouri)
160 161
162 -def set_pyro_log_threshold(level):
163 pyrologger = logging.getLogger('Pyro.%s' % str(id(util.Log))) 164 # remove handlers so only the root handler is used 165 pyrologger.handlers = [] 166 pyrologger.setLevel(level)
167