##// END OF EJS Templates
Merge pull request #1868 from minrk/ipc...
Bussonnier Matthias -
r8501:af13023a merge
parent child Browse files
Show More
@@ -24,6 +24,7 b' Authors:'
24 import atexit
24 import atexit
25 import json
25 import json
26 import os
26 import os
27 import shutil
27 import signal
28 import signal
28 import sys
29 import sys
29 import uuid
30 import uuid
@@ -38,7 +39,7 b' from IPython.zmq.blockingkernelmanager import BlockingKernelManager'
38 from IPython.utils.path import filefind
39 from IPython.utils.path import filefind
39 from IPython.utils.py3compat import str_to_bytes
40 from IPython.utils.py3compat import str_to_bytes
40 from IPython.utils.traitlets import (
41 from IPython.utils.traitlets import (
41 Dict, List, Unicode, CUnicode, Int, CBool, Any
42 Dict, List, Unicode, CUnicode, Int, CBool, Any, CaselessStrEnum
42 )
43 )
43 from IPython.zmq.ipkernel import (
44 from IPython.zmq.ipkernel import (
44 flags as ipkernel_flags,
45 flags as ipkernel_flags,
@@ -151,12 +152,27 b' class IPythonConsoleApp(Configurable):'
151 # create requested profiles by default, if they don't exist:
152 # create requested profiles by default, if they don't exist:
152 auto_create = CBool(True)
153 auto_create = CBool(True)
153 # connection info:
154 # connection info:
154 ip = Unicode(LOCALHOST, config=True,
155
156 transport = CaselessStrEnum(['tcp', 'ipc'], default_value='tcp', config=True)
157
158 ip = Unicode(config=True,
155 help="""Set the kernel\'s IP address [default localhost].
159 help="""Set the kernel\'s IP address [default localhost].
156 If the IP address is something other than localhost, then
160 If the IP address is something other than localhost, then
157 Consoles on other machines will be able to connect
161 Consoles on other machines will be able to connect
158 to the Kernel, so be careful!"""
162 to the Kernel, so be careful!"""
159 )
163 )
164 def _ip_default(self):
165 if self.transport == 'tcp':
166 return LOCALHOST
167 else:
168 # this can fire early if ip is given,
169 # in which case our return value is meaningless
170 if not hasattr(self, 'profile_dir'):
171 return ''
172 ipcdir = os.path.join(self.profile_dir.security_dir, 'kernel-%s' % os.getpid())
173 os.makedirs(ipcdir)
174 atexit.register(lambda : shutil.rmtree(ipcdir))
175 return os.path.join(ipcdir, 'ipc')
160
176
161 sshserver = Unicode('', config=True,
177 sshserver = Unicode('', config=True,
162 help="""The SSH server to use to connect to the kernel.""")
178 help="""The SSH server to use to connect to the kernel.""")
@@ -256,10 +272,10 b' class IPythonConsoleApp(Configurable):'
256 return
272 return
257 self.log.debug(u"Loading connection file %s", fname)
273 self.log.debug(u"Loading connection file %s", fname)
258 with open(fname) as f:
274 with open(fname) as f:
259 s = f.read()
275 cfg = json.load(f)
260 cfg = json.loads(s)
276
261 if self.ip == LOCALHOST and 'ip' in cfg:
277 self.transport = cfg.get('transport', 'tcp')
262 # not overridden by config or cl_args
278 if 'ip' in cfg:
263 self.ip = cfg['ip']
279 self.ip = cfg['ip']
264 for channel in ('hb', 'shell', 'iopub', 'stdin'):
280 for channel in ('hb', 'shell', 'iopub', 'stdin'):
265 name = channel + '_port'
281 name = channel + '_port'
@@ -268,12 +284,17 b' class IPythonConsoleApp(Configurable):'
268 setattr(self, name, cfg[name])
284 setattr(self, name, cfg[name])
269 if 'key' in cfg:
285 if 'key' in cfg:
270 self.config.Session.key = str_to_bytes(cfg['key'])
286 self.config.Session.key = str_to_bytes(cfg['key'])
287
271
288
272 def init_ssh(self):
289 def init_ssh(self):
273 """set up ssh tunnels, if needed."""
290 """set up ssh tunnels, if needed."""
274 if not self.sshserver and not self.sshkey:
291 if not self.sshserver and not self.sshkey:
275 return
292 return
276
293
294 if self.transport != 'tcp':
295 self.log.error("Can only use ssh tunnels with TCP sockets, not %s", self.transport)
296 return
297
277 if self.sshkey and not self.sshserver:
298 if self.sshkey and not self.sshserver:
278 # specifying just the key implies that we are connecting directly
299 # specifying just the key implies that we are connecting directly
279 self.sshserver = self.ip
300 self.sshserver = self.ip
@@ -326,6 +347,7 b' class IPythonConsoleApp(Configurable):'
326
347
327 # Create a KernelManager and start a kernel.
348 # Create a KernelManager and start a kernel.
328 self.kernel_manager = self.kernel_manager_class(
349 self.kernel_manager = self.kernel_manager_class(
350 transport=self.transport,
329 ip=self.ip,
351 ip=self.ip,
330 shell_port=self.shell_port,
352 shell_port=self.shell_port,
331 iopub_port=self.iopub_port,
353 iopub_port=self.iopub_port,
@@ -21,7 +21,7 b' from IPython.utils.py3compat import bytes_to_str'
21 from parentpoller import ParentPollerWindows
21 from parentpoller import ParentPollerWindows
22
22
23 def write_connection_file(fname=None, shell_port=0, iopub_port=0, stdin_port=0, hb_port=0,
23 def write_connection_file(fname=None, shell_port=0, iopub_port=0, stdin_port=0, hb_port=0,
24 ip=LOCALHOST, key=b''):
24 ip=LOCALHOST, key=b'', transport='tcp'):
25 """Generates a JSON config file, including the selection of random ports.
25 """Generates a JSON config file, including the selection of random ports.
26
26
27 Parameters
27 Parameters
@@ -54,17 +54,26 b' def write_connection_file(fname=None, shell_port=0, iopub_port=0, stdin_port=0, '
54 fname = tempfile.mktemp('.json')
54 fname = tempfile.mktemp('.json')
55
55
56 # Find open ports as necessary.
56 # Find open ports as necessary.
57
57 ports = []
58 ports = []
58 ports_needed = int(shell_port <= 0) + int(iopub_port <= 0) + \
59 ports_needed = int(shell_port <= 0) + int(iopub_port <= 0) + \
59 int(stdin_port <= 0) + int(hb_port <= 0)
60 int(stdin_port <= 0) + int(hb_port <= 0)
60 for i in xrange(ports_needed):
61 if transport == 'tcp':
61 sock = socket.socket()
62 for i in range(ports_needed):
62 sock.bind(('', 0))
63 sock = socket.socket()
63 ports.append(sock)
64 sock.bind(('', 0))
64 for i, sock in enumerate(ports):
65 ports.append(sock)
65 port = sock.getsockname()[1]
66 for i, sock in enumerate(ports):
66 sock.close()
67 port = sock.getsockname()[1]
67 ports[i] = port
68 sock.close()
69 ports[i] = port
70 else:
71 N = 1
72 for i in range(ports_needed):
73 while os.path.exists("%s-%s" % (ip, str(N))):
74 N += 1
75 ports.append(N)
76 N += 1
68 if shell_port <= 0:
77 if shell_port <= 0:
69 shell_port = ports.pop(0)
78 shell_port = ports.pop(0)
70 if iopub_port <= 0:
79 if iopub_port <= 0:
@@ -81,6 +90,7 b' def write_connection_file(fname=None, shell_port=0, iopub_port=0, stdin_port=0, '
81 )
90 )
82 cfg['ip'] = ip
91 cfg['ip'] = ip
83 cfg['key'] = bytes_to_str(key)
92 cfg['key'] = bytes_to_str(key)
93 cfg['transport'] = transport
84
94
85 with open(fname, 'w') as f:
95 with open(fname, 'w') as f:
86 f.write(json.dumps(cfg, indent=2))
96 f.write(json.dumps(cfg, indent=2))
@@ -12,6 +12,7 b''
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 import os
15 import socket
16 import socket
16 import sys
17 import sys
17 from threading import Thread
18 from threading import Thread
@@ -28,21 +29,28 b' from IPython.utils.localinterfaces import LOCALHOST'
28 class Heartbeat(Thread):
29 class Heartbeat(Thread):
29 "A simple ping-pong style heartbeat that runs in a thread."
30 "A simple ping-pong style heartbeat that runs in a thread."
30
31
31 def __init__(self, context, addr=(LOCALHOST, 0)):
32 def __init__(self, context, addr=('tcp', LOCALHOST, 0)):
32 Thread.__init__(self)
33 Thread.__init__(self)
33 self.context = context
34 self.context = context
34 self.ip, self.port = addr
35 self.transport, self.ip, self.port = addr
35 if self.port == 0:
36 if self.port == 0:
36 s = socket.socket()
37 if addr[0] == 'tcp':
37 # '*' means all interfaces to 0MQ, which is '' to socket.socket
38 s = socket.socket()
38 s.bind(('' if self.ip == '*' else self.ip, 0))
39 # '*' means all interfaces to 0MQ, which is '' to socket.socket
39 self.port = s.getsockname()[1]
40 s.bind(('' if self.ip == '*' else self.ip, 0))
40 s.close()
41 self.port = s.getsockname()[1]
42 s.close()
43 elif addr[0] == 'ipc':
44 while os.path.exists(self.ip + '-' + self.port):
45 self.port = self.port + 1
46 else:
47 raise ValueError("Unrecognized zmq transport: %s" % addr[0])
41 self.addr = (self.ip, self.port)
48 self.addr = (self.ip, self.port)
42 self.daemon = True
49 self.daemon = True
43
50
44 def run(self):
51 def run(self):
45 self.socket = self.context.socket(zmq.REP)
52 self.socket = self.context.socket(zmq.REP)
46 self.socket.bind('tcp://%s:%i' % self.addr)
53 c = ':' if self.transport == 'tcp' else '-'
54 self.socket.bind('%s://%s' % (self.transport, self.ip) + c + str(self.port))
47 zmq.device(zmq.FORWARDER, self.socket, self.socket)
55 zmq.device(zmq.FORWARDER, self.socket, self.socket)
48
56
@@ -35,8 +35,10 b' from IPython.utils import io'
35 from IPython.utils.localinterfaces import LOCALHOST
35 from IPython.utils.localinterfaces import LOCALHOST
36 from IPython.utils.path import filefind
36 from IPython.utils.path import filefind
37 from IPython.utils.py3compat import str_to_bytes
37 from IPython.utils.py3compat import str_to_bytes
38 from IPython.utils.traitlets import (Any, Instance, Dict, Unicode, Integer, Bool,
38 from IPython.utils.traitlets import (
39 DottedObjectName)
39 Any, Instance, Dict, Unicode, Integer, Bool, CaselessStrEnum,
40 DottedObjectName,
41 )
40 from IPython.utils.importstring import import_item
42 from IPython.utils.importstring import import_item
41 # local imports
43 # local imports
42 from IPython.zmq.entry_point import write_connection_file
44 from IPython.zmq.entry_point import write_connection_file
@@ -109,6 +111,7 b' class KernelApp(BaseIPythonApplication):'
109 self.config_file_specified = False
111 self.config_file_specified = False
110
112
111 # connection info:
113 # connection info:
114 transport = CaselessStrEnum(['tcp', 'ipc'], default_value='tcp', config=True)
112 ip = Unicode(LOCALHOST, config=True,
115 ip = Unicode(LOCALHOST, config=True,
113 help="Set the IP or interface on which the kernel will listen.")
116 help="Set the IP or interface on which the kernel will listen.")
114 hb_port = Integer(0, config=True, help="set the heartbeat port [default: random]")
117 hb_port = Integer(0, config=True, help="set the heartbeat port [default: random]")
@@ -154,11 +157,12 b' class KernelApp(BaseIPythonApplication):'
154 self.poller = ParentPollerUnix()
157 self.poller = ParentPollerUnix()
155
158
156 def _bind_socket(self, s, port):
159 def _bind_socket(self, s, port):
157 iface = 'tcp://%s' % self.ip
160 iface = '%s://%s' % (self.transport, self.ip)
158 if port <= 0:
161 if port <= 0 and self.transport == 'tcp':
159 port = s.bind_to_random_port(iface)
162 port = s.bind_to_random_port(iface)
160 else:
163 else:
161 s.bind(iface + ':%i'%port)
164 c = ':' if self.transport == 'tcp' else '-'
165 s.bind(iface + c + str(port))
162 return port
166 return port
163
167
164 def load_connection_file(self):
168 def load_connection_file(self):
@@ -174,6 +178,7 b' class KernelApp(BaseIPythonApplication):'
174 with open(fname) as f:
178 with open(fname) as f:
175 s = f.read()
179 s = f.read()
176 cfg = json.loads(s)
180 cfg = json.loads(s)
181 self.transport = cfg.get('transport', self.transport)
177 if self.ip == LOCALHOST and 'ip' in cfg:
182 if self.ip == LOCALHOST and 'ip' in cfg:
178 # not overridden by config or cl_args
183 # not overridden by config or cl_args
179 self.ip = cfg['ip']
184 self.ip = cfg['ip']
@@ -191,7 +196,7 b' class KernelApp(BaseIPythonApplication):'
191 cf = os.path.join(self.profile_dir.security_dir, self.connection_file)
196 cf = os.path.join(self.profile_dir.security_dir, self.connection_file)
192 else:
197 else:
193 cf = self.connection_file
198 cf = self.connection_file
194 write_connection_file(cf, ip=self.ip, key=self.session.key,
199 write_connection_file(cf, ip=self.ip, key=self.session.key, transport=self.transport,
195 shell_port=self.shell_port, stdin_port=self.stdin_port, hb_port=self.hb_port,
200 shell_port=self.shell_port, stdin_port=self.stdin_port, hb_port=self.hb_port,
196 iopub_port=self.iopub_port)
201 iopub_port=self.iopub_port)
197
202
@@ -204,6 +209,19 b' class KernelApp(BaseIPythonApplication):'
204 os.remove(cf)
209 os.remove(cf)
205 except (IOError, OSError):
210 except (IOError, OSError):
206 pass
211 pass
212
213 self._cleanup_ipc_files()
214
215 def _cleanup_ipc_files(self):
216 """cleanup ipc files if we wrote them"""
217 if self.transport != 'ipc':
218 return
219 for port in (self.shell_port, self.iopub_port, self.stdin_port, self.hb_port):
220 ipcfile = "%s-%i" % (self.ip, port)
221 try:
222 os.remove(ipcfile)
223 except (IOError, OSError):
224 pass
207
225
208 def init_connection_file(self):
226 def init_connection_file(self):
209 if not self.connection_file:
227 if not self.connection_file:
@@ -238,7 +256,7 b' class KernelApp(BaseIPythonApplication):'
238 # heartbeat doesn't share context, because it mustn't be blocked
256 # heartbeat doesn't share context, because it mustn't be blocked
239 # by the GIL, which is accessed by libzmq when freeing zero-copy messages
257 # by the GIL, which is accessed by libzmq when freeing zero-copy messages
240 hb_ctx = zmq.Context()
258 hb_ctx = zmq.Context()
241 self.heartbeat = Heartbeat(hb_ctx, (self.ip, self.hb_port))
259 self.heartbeat = Heartbeat(hb_ctx, (self.transport, self.ip, self.hb_port))
242 self.hb_port = self.heartbeat.port
260 self.hb_port = self.heartbeat.port
243 self.log.debug("Heartbeat REP Channel on port: %i"%self.hb_port)
261 self.log.debug("Heartbeat REP Channel on port: %i"%self.hb_port)
244 self.heartbeat.start()
262 self.heartbeat.start()
@@ -37,7 +37,7 b' from zmq.eventloop import ioloop, zmqstream'
37 from IPython.config.loader import Config
37 from IPython.config.loader import Config
38 from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS
38 from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS
39 from IPython.utils.traitlets import (
39 from IPython.utils.traitlets import (
40 HasTraits, Any, Instance, Type, Unicode, Integer, Bool
40 HasTraits, Any, Instance, Type, Unicode, Integer, Bool, CaselessStrEnum
41 )
41 )
42 from IPython.utils.py3compat import str_to_bytes
42 from IPython.utils.py3compat import str_to_bytes
43 from IPython.zmq.entry_point import write_connection_file
43 from IPython.zmq.entry_point import write_connection_file
@@ -103,7 +103,7 b' class ZMQSocketChannel(Thread):'
103 The ZMQ context to use.
103 The ZMQ context to use.
104 session : :class:`session.Session`
104 session : :class:`session.Session`
105 The session to use.
105 The session to use.
106 address : tuple
106 address : zmq url
107 Standard (ip, port) tuple that the kernel is listening on.
107 Standard (ip, port) tuple that the kernel is listening on.
108 """
108 """
109 super(ZMQSocketChannel, self).__init__()
109 super(ZMQSocketChannel, self).__init__()
@@ -111,9 +111,11 b' class ZMQSocketChannel(Thread):'
111
111
112 self.context = context
112 self.context = context
113 self.session = session
113 self.session = session
114 if address[1] == 0:
114 if isinstance(address, tuple):
115 message = 'The port number for a channel cannot be 0.'
115 if address[1] == 0:
116 raise InvalidPortNumber(message)
116 message = 'The port number for a channel cannot be 0.'
117 raise InvalidPortNumber(message)
118 address = "tcp://%s:%i" % address
117 self._address = address
119 self._address = address
118 atexit.register(self._notice_exit)
120 atexit.register(self._notice_exit)
119
121
@@ -149,10 +151,7 b' class ZMQSocketChannel(Thread):'
149
151
150 @property
152 @property
151 def address(self):
153 def address(self):
152 """Get the channel's address as an (ip, port) tuple.
154 """Get the channel's address as a zmq url string ('tcp://127.0.0.1:5555').
153
154 By the default, the address is (localhost, 0), where 0 means a random
155 port.
156 """
155 """
157 return self._address
156 return self._address
158
157
@@ -196,7 +195,7 b' class ShellSocketChannel(ZMQSocketChannel):'
196 """The thread's main activity. Call start() instead."""
195 """The thread's main activity. Call start() instead."""
197 self.socket = self.context.socket(zmq.DEALER)
196 self.socket = self.context.socket(zmq.DEALER)
198 self.socket.setsockopt(zmq.IDENTITY, self.session.bsession)
197 self.socket.setsockopt(zmq.IDENTITY, self.session.bsession)
199 self.socket.connect('tcp://%s:%i' % self.address)
198 self.socket.connect(self.address)
200 self.stream = zmqstream.ZMQStream(self.socket, self.ioloop)
199 self.stream = zmqstream.ZMQStream(self.socket, self.ioloop)
201 self.stream.on_recv(self._handle_recv)
200 self.stream.on_recv(self._handle_recv)
202 self._run_loop()
201 self._run_loop()
@@ -396,7 +395,7 b' class SubSocketChannel(ZMQSocketChannel):'
396 self.socket = self.context.socket(zmq.SUB)
395 self.socket = self.context.socket(zmq.SUB)
397 self.socket.setsockopt(zmq.SUBSCRIBE,b'')
396 self.socket.setsockopt(zmq.SUBSCRIBE,b'')
398 self.socket.setsockopt(zmq.IDENTITY, self.session.bsession)
397 self.socket.setsockopt(zmq.IDENTITY, self.session.bsession)
399 self.socket.connect('tcp://%s:%i' % self.address)
398 self.socket.connect(self.address)
400 self.stream = zmqstream.ZMQStream(self.socket, self.ioloop)
399 self.stream = zmqstream.ZMQStream(self.socket, self.ioloop)
401 self.stream.on_recv(self._handle_recv)
400 self.stream.on_recv(self._handle_recv)
402 self._run_loop()
401 self._run_loop()
@@ -462,7 +461,7 b' class StdInSocketChannel(ZMQSocketChannel):'
462 """The thread's main activity. Call start() instead."""
461 """The thread's main activity. Call start() instead."""
463 self.socket = self.context.socket(zmq.DEALER)
462 self.socket = self.context.socket(zmq.DEALER)
464 self.socket.setsockopt(zmq.IDENTITY, self.session.bsession)
463 self.socket.setsockopt(zmq.IDENTITY, self.session.bsession)
465 self.socket.connect('tcp://%s:%i' % self.address)
464 self.socket.connect(self.address)
466 self.stream = zmqstream.ZMQStream(self.socket, self.ioloop)
465 self.stream = zmqstream.ZMQStream(self.socket, self.ioloop)
467 self.stream.on_recv(self._handle_recv)
466 self.stream.on_recv(self._handle_recv)
468 self._run_loop()
467 self._run_loop()
@@ -521,7 +520,7 b' class HBSocketChannel(ZMQSocketChannel):'
521 self.socket.close()
520 self.socket.close()
522 self.socket = self.context.socket(zmq.REQ)
521 self.socket = self.context.socket(zmq.REQ)
523 self.socket.setsockopt(zmq.LINGER, 0)
522 self.socket.setsockopt(zmq.LINGER, 0)
524 self.socket.connect('tcp://%s:%i' % self.address)
523 self.socket.connect(self.address)
525
524
526 self.poller.register(self.socket, zmq.POLLIN)
525 self.poller.register(self.socket, zmq.POLLIN)
527
526
@@ -660,6 +659,10 b' class KernelManager(HasTraits):'
660
659
661 # The addresses for the communication channels.
660 # The addresses for the communication channels.
662 connection_file = Unicode('')
661 connection_file = Unicode('')
662
663 transport = CaselessStrEnum(['tcp', 'ipc'], default_value='tcp')
664
665
663 ip = Unicode(LOCALHOST)
666 ip = Unicode(LOCALHOST)
664 def _ip_changed(self, name, old, new):
667 def _ip_changed(self, name, old, new):
665 if new == '*':
668 if new == '*':
@@ -748,7 +751,20 b' class KernelManager(HasTraits):'
748 self._connection_file_written = False
751 self._connection_file_written = False
749 try:
752 try:
750 os.remove(self.connection_file)
753 os.remove(self.connection_file)
751 except OSError:
754 except (IOError, OSError):
755 pass
756
757 self._cleanup_ipc_files()
758
759 def _cleanup_ipc_files(self):
760 """cleanup ipc files if we wrote them"""
761 if self.transport != 'ipc':
762 return
763 for port in (self.shell_port, self.iopub_port, self.stdin_port, self.hb_port):
764 ipcfile = "%s-%i" % (self.ip, port)
765 try:
766 os.remove(ipcfile)
767 except (IOError, OSError):
752 pass
768 pass
753
769
754 def load_connection_file(self):
770 def load_connection_file(self):
@@ -756,6 +772,9 b' class KernelManager(HasTraits):'
756 with open(self.connection_file) as f:
772 with open(self.connection_file) as f:
757 cfg = json.loads(f.read())
773 cfg = json.loads(f.read())
758
774
775 from pprint import pprint
776 pprint(cfg)
777 self.transport = cfg.get('transport', 'tcp')
759 self.ip = cfg['ip']
778 self.ip = cfg['ip']
760 self.shell_port = cfg['shell_port']
779 self.shell_port = cfg['shell_port']
761 self.stdin_port = cfg['stdin_port']
780 self.stdin_port = cfg['stdin_port']
@@ -768,7 +787,7 b' class KernelManager(HasTraits):'
768 if self._connection_file_written:
787 if self._connection_file_written:
769 return
788 return
770 self.connection_file,cfg = write_connection_file(self.connection_file,
789 self.connection_file,cfg = write_connection_file(self.connection_file,
771 ip=self.ip, key=self.session.key,
790 transport=self.transport, ip=self.ip, key=self.session.key,
772 stdin_port=self.stdin_port, iopub_port=self.iopub_port,
791 stdin_port=self.stdin_port, iopub_port=self.iopub_port,
773 shell_port=self.shell_port, hb_port=self.hb_port)
792 shell_port=self.shell_port, hb_port=self.hb_port)
774 # write_connection_file also sets default ports:
793 # write_connection_file also sets default ports:
@@ -795,7 +814,7 b' class KernelManager(HasTraits):'
795 **kw : optional
814 **kw : optional
796 See respective options for IPython and Python kernels.
815 See respective options for IPython and Python kernels.
797 """
816 """
798 if self.ip not in LOCAL_IPS:
817 if self.transport == 'tcp' and self.ip not in LOCAL_IPS:
799 raise RuntimeError("Can only launch a kernel on a local interface. "
818 raise RuntimeError("Can only launch a kernel on a local interface. "
800 "Make sure that the '*_address' attributes are "
819 "Make sure that the '*_address' attributes are "
801 "configured properly. "
820 "configured properly. "
@@ -974,13 +993,21 b' class KernelManager(HasTraits):'
974 # Channels used for communication with the kernel:
993 # Channels used for communication with the kernel:
975 #--------------------------------------------------------------------------
994 #--------------------------------------------------------------------------
976
995
996 def _make_url(self, port):
997 """make a zmq url with a port"""
998 if self.transport == 'tcp':
999 return "tcp://%s:%i" % (self.ip, port)
1000 else:
1001 return "%s://%s-%s" % (self.transport, self.ip, port)
1002
977 @property
1003 @property
978 def shell_channel(self):
1004 def shell_channel(self):
979 """Get the REQ socket channel object to make requests of the kernel."""
1005 """Get the REQ socket channel object to make requests of the kernel."""
980 if self._shell_channel is None:
1006 if self._shell_channel is None:
981 self._shell_channel = self.shell_channel_class(self.context,
1007 self._shell_channel = self.shell_channel_class(self.context,
982 self.session,
1008 self.session,
983 (self.ip, self.shell_port))
1009 self._make_url(self.shell_port),
1010 )
984 return self._shell_channel
1011 return self._shell_channel
985
1012
986 @property
1013 @property
@@ -989,7 +1016,8 b' class KernelManager(HasTraits):'
989 if self._sub_channel is None:
1016 if self._sub_channel is None:
990 self._sub_channel = self.sub_channel_class(self.context,
1017 self._sub_channel = self.sub_channel_class(self.context,
991 self.session,
1018 self.session,
992 (self.ip, self.iopub_port))
1019 self._make_url(self.iopub_port),
1020 )
993 return self._sub_channel
1021 return self._sub_channel
994
1022
995 @property
1023 @property
@@ -997,8 +1025,9 b' class KernelManager(HasTraits):'
997 """Get the REP socket channel object to handle stdin (raw_input)."""
1025 """Get the REP socket channel object to handle stdin (raw_input)."""
998 if self._stdin_channel is None:
1026 if self._stdin_channel is None:
999 self._stdin_channel = self.stdin_channel_class(self.context,
1027 self._stdin_channel = self.stdin_channel_class(self.context,
1000 self.session,
1028 self.session,
1001 (self.ip, self.stdin_port))
1029 self._make_url(self.stdin_port),
1030 )
1002 return self._stdin_channel
1031 return self._stdin_channel
1003
1032
1004 @property
1033 @property
@@ -1007,6 +1036,7 b' class KernelManager(HasTraits):'
1007 kernel is alive."""
1036 kernel is alive."""
1008 if self._hb_channel is None:
1037 if self._hb_channel is None:
1009 self._hb_channel = self.hb_channel_class(self.context,
1038 self._hb_channel = self.hb_channel_class(self.context,
1010 self.session,
1039 self.session,
1011 (self.ip, self.hb_port))
1040 self._make_url(self.hb_port),
1041 )
1012 return self._hb_channel
1042 return self._hb_channel
General Comments 0
You need to be logged in to leave comments. Login now