forked from ipython/ipython
-
Notifications
You must be signed in to change notification settings - Fork 1
/
clientconnector.py
150 lines (120 loc) · 4.97 KB
/
clientconnector.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# 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
from IPython.config.cutils import import_item
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