clientconnector.py
150 lines
| 5.0 KiB
| text/x-python
|
PythonLexer
Brian E Granger
|
r1234 | # encoding: utf-8 | ||
"""A class for handling client connections to the controller.""" | ||||
__docformat__ = "restructuredtext en" | ||||
#------------------------------------------------------------------------------- | ||||
# Copyright (C) 2008 The IPython Development Team | ||||
# | ||||
# Distributed under the terms of the BSD License. The full license is in | ||||
# the file COPYING, distributed as part of this software. | ||||
#------------------------------------------------------------------------------- | ||||
#------------------------------------------------------------------------------- | ||||
# Imports | ||||
#------------------------------------------------------------------------------- | ||||
from twisted.internet import defer | ||||
from IPython.kernel.fcutil import Tub, UnauthenticatedTub | ||||
from IPython.kernel.config import config_manager as kernel_config_manager | ||||
Brian Granger
|
r2229 | from IPython.utils.importstring import import_item | ||
Brian E Granger
|
r1234 | from IPython.kernel.fcutil import find_furl | ||
co = kernel_config_manager.get_config_obj() | ||||
client_co = co['client'] | ||||
#------------------------------------------------------------------------------- | ||||
# The ClientConnector class | ||||
#------------------------------------------------------------------------------- | ||||
class ClientConnector(object): | ||||
""" | ||||
This class gets remote references from furls and returns the wrapped clients. | ||||
This class is also used in `client.py` and `asyncclient.py` to create | ||||
a single per client-process Tub. | ||||
""" | ||||
def __init__(self): | ||||
self._remote_refs = {} | ||||
self.tub = Tub() | ||||
self.tub.startService() | ||||
def get_reference(self, furl_or_file): | ||||
""" | ||||
Get a remote reference using a furl or a file containing a furl. | ||||
Remote references are cached locally so once a remote reference | ||||
has been retrieved for a given furl, the cached version is | ||||
returned. | ||||
:Parameters: | ||||
furl_or_file : str | ||||
A furl or a filename containing a furl | ||||
:Returns: | ||||
A deferred to a remote reference | ||||
""" | ||||
furl = find_furl(furl_or_file) | ||||
if furl in self._remote_refs: | ||||
d = defer.succeed(self._remote_refs[furl]) | ||||
else: | ||||
d = self.tub.getReference(furl) | ||||
d.addCallback(self.save_ref, furl) | ||||
return d | ||||
def save_ref(self, ref, furl): | ||||
""" | ||||
Cache a remote reference by its furl. | ||||
""" | ||||
self._remote_refs[furl] = ref | ||||
return ref | ||||
def get_task_client(self, furl_or_file=''): | ||||
""" | ||||
Get the task controller client. | ||||
This method is a simple wrapper around `get_client` that allow | ||||
`furl_or_file` to be empty, in which case, the furls is taken | ||||
from the default furl file given in the configuration. | ||||
:Parameters: | ||||
furl_or_file : str | ||||
A furl or a filename containing a furl. If empty, the | ||||
default furl_file will be used | ||||
:Returns: | ||||
A deferred to the actual client class | ||||
""" | ||||
task_co = client_co['client_interfaces']['task'] | ||||
if furl_or_file: | ||||
ff = furl_or_file | ||||
else: | ||||
ff = task_co['furl_file'] | ||||
return self.get_client(ff) | ||||
def get_multiengine_client(self, furl_or_file=''): | ||||
""" | ||||
Get the multiengine controller client. | ||||
This method is a simple wrapper around `get_client` that allow | ||||
`furl_or_file` to be empty, in which case, the furls is taken | ||||
from the default furl file given in the configuration. | ||||
:Parameters: | ||||
furl_or_file : str | ||||
A furl or a filename containing a furl. If empty, the | ||||
default furl_file will be used | ||||
:Returns: | ||||
A deferred to the actual client class | ||||
""" | ||||
task_co = client_co['client_interfaces']['multiengine'] | ||||
if furl_or_file: | ||||
ff = furl_or_file | ||||
else: | ||||
ff = task_co['furl_file'] | ||||
return self.get_client(ff) | ||||
def get_client(self, furl_or_file): | ||||
""" | ||||
Get a remote reference and wrap it in a client by furl. | ||||
This method first gets a remote reference and then calls its | ||||
`get_client_name` method to find the apprpriate client class | ||||
that should be used to wrap the remote reference. | ||||
:Parameters: | ||||
furl_or_file : str | ||||
A furl or a filename containing a furl | ||||
:Returns: | ||||
A deferred to the actual client class | ||||
""" | ||||
furl = find_furl(furl_or_file) | ||||
d = self.get_reference(furl) | ||||
def wrap_remote_reference(rr): | ||||
d = rr.callRemote('get_client_name') | ||||
d.addCallback(lambda name: import_item(name)) | ||||
def adapt(client_interface): | ||||
client = client_interface(rr) | ||||
client.tub = self.tub | ||||
return client | ||||
d.addCallback(adapt) | ||||
return d | ||||
d.addCallback(wrap_remote_reference) | ||||
return d | ||||