##// END OF EJS Templates
s/destroy/close
MinRK -
Show More
@@ -1,142 +1,142 b''
1 """Base class to manage comms"""
1 """Base class to manage comms"""
2
2
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2013 The IPython Development Team
4 # Copyright (C) 2013 The IPython Development Team
5 #
5 #
6 # Distributed under the terms of the BSD License. The full license is in
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
7 # the file COPYING, distributed as part of this software.
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9
9
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Imports
11 # Imports
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 from IPython.config import LoggingConfigurable
14 from IPython.config import LoggingConfigurable
15 from IPython.core.prompts import LazyEvaluate
15 from IPython.core.prompts import LazyEvaluate
16 from IPython.core.getipython import get_ipython
16 from IPython.core.getipython import get_ipython
17
17
18 from IPython.utils.importstring import import_item
18 from IPython.utils.importstring import import_item
19 from IPython.utils.traitlets import Instance, Unicode, Dict, Any
19 from IPython.utils.traitlets import Instance, Unicode, Dict, Any
20
20
21 from .comm import Comm
21 from .comm import Comm
22
22
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24 # Code
24 # Code
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26
26
27 def lazy_keys(dikt):
27 def lazy_keys(dikt):
28 """Return lazy-evaluated string representation of a dictionary's keys
28 """Return lazy-evaluated string representation of a dictionary's keys
29
29
30 Key list is only constructed if it will actually be used.
30 Key list is only constructed if it will actually be used.
31 Used for debug-logging.
31 Used for debug-logging.
32 """
32 """
33 return LazyEvaluate(lambda d: list(d.keys()))
33 return LazyEvaluate(lambda d: list(d.keys()))
34
34
35
35
36 class CommManager(LoggingConfigurable):
36 class CommManager(LoggingConfigurable):
37 """Manager for Comms in the Kernel"""
37 """Manager for Comms in the Kernel"""
38
38
39 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
39 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
40 def _shell_default(self):
40 def _shell_default(self):
41 return get_ipython()
41 return get_ipython()
42 iopub_socket = Any()
42 iopub_socket = Any()
43 def _iopub_socket_default(self):
43 def _iopub_socket_default(self):
44 return self.shell.parent.iopub_socket
44 return self.shell.parent.iopub_socket
45 session = Instance('IPython.kernel.zmq.session.Session')
45 session = Instance('IPython.kernel.zmq.session.Session')
46 def _session_default(self):
46 def _session_default(self):
47 if self.shell is None:
47 if self.shell is None:
48 return
48 return
49 return self.shell.parent.session
49 return self.shell.parent.session
50
50
51 comms = Dict()
51 comms = Dict()
52 targets = Dict()
52 targets = Dict()
53
53
54 # Public APIs
54 # Public APIs
55
55
56 def register_target(self, target, f):
56 def register_target(self, target, f):
57 """Register a callable f for a given target
57 """Register a callable f for a given target
58
58
59 f will be called with a Comm object as its only argument
59 f will be called with a Comm object as its only argument
60 when a comm_open message is received with `target`.
60 when a comm_open message is received with `target`.
61
61
62 f can be a Python callable or an import string for one.
62 f can be a Python callable or an import string for one.
63 """
63 """
64 if isinstance(f, basestring):
64 if isinstance(f, basestring):
65 f = import_item(f)
65 f = import_item(f)
66
66
67 self.targets[target] = f
67 self.targets[target] = f
68
68
69 def register_comm(self, comm):
69 def register_comm(self, comm):
70 """Register a new comm"""
70 """Register a new comm"""
71 comm_id = comm.comm_id
71 comm_id = comm.comm_id
72 comm.shell = self.shell
72 comm.shell = self.shell
73 comm.iopub_socket = self.iopub_socket
73 comm.iopub_socket = self.iopub_socket
74 self.comms[comm_id] = comm
74 self.comms[comm_id] = comm
75 return comm_id
75 return comm_id
76
76
77 def unregister_comm(self, comm_id):
77 def unregister_comm(self, comm_id):
78 """Unregister a comm, and close its counterpart"""
78 """Unregister a comm, and close its counterpart"""
79 # unlike get_comm, this should raise a KeyError
79 # unlike get_comm, this should raise a KeyError
80 comm = self.comms.pop(comm_id)
80 comm = self.comms.pop(comm_id)
81 comm.close()
81 comm.close()
82
82
83 def get_comm(self, comm_id):
83 def get_comm(self, comm_id):
84 """Get a comm with a particular id
84 """Get a comm with a particular id
85
85
86 Returns the comm if found, otherwise None.
86 Returns the comm if found, otherwise None.
87
87
88 This will not raise an error,
88 This will not raise an error,
89 it will log messages if the comm cannot be found.
89 it will log messages if the comm cannot be found.
90 """
90 """
91 if comm_id not in self.comms:
91 if comm_id not in self.comms:
92 self.log.error("No such comm: %s", comm_id)
92 self.log.error("No such comm: %s", comm_id)
93 self.log.debug("Current comms: %s", lazy_keys(self.comms))
93 self.log.debug("Current comms: %s", lazy_keys(self.comms))
94 return
94 return
95 # call, because we store weakrefs
95 # call, because we store weakrefs
96 comm = self.comms[comm_id]
96 comm = self.comms[comm_id]
97 return comm
97 return comm
98
98
99 # Message handlers
99 # Message handlers
100
100
101 def comm_open(self, stream, ident, msg):
101 def comm_open(self, stream, ident, msg):
102 """Handler for comm_open messages"""
102 """Handler for comm_open messages"""
103 content = msg['content']
103 content = msg['content']
104 comm_id = content['comm_id']
104 comm_id = content['comm_id']
105 target = content['target']
105 target = content['target']
106 callback = self.targets.get(target, None)
106 callback = self.targets.get(target, None)
107 comm = Comm(comm_id=comm_id,
107 comm = Comm(comm_id=comm_id,
108 shell=self.shell,
108 shell=self.shell,
109 iopub_socket=self.iopub_socket,
109 iopub_socket=self.iopub_socket,
110 _open_data=content['data'],
110 _open_data=content['data'],
111 primary=False,
111 primary=False,
112 )
112 )
113 if callback is None:
113 if callback is None:
114 self.log.error("No such comm target registered: %s", target)
114 self.log.error("No such comm target registered: %s", target)
115 comm.destroy()
115 comm.close()
116 return
116 return
117 callback(comm)
117 callback(comm)
118 self.register_comm(comm)
118 self.register_comm(comm)
119
119
120 def comm_msg(self, stream, ident, msg):
120 def comm_msg(self, stream, ident, msg):
121 """Handler for comm_msg messages"""
121 """Handler for comm_msg messages"""
122 content = msg['content']
122 content = msg['content']
123 comm_id = content['comm_id']
123 comm_id = content['comm_id']
124 comm = self.get_comm(comm_id)
124 comm = self.get_comm(comm_id)
125 if comm is None:
125 if comm is None:
126 # no such comm
126 # no such comm
127 return
127 return
128 comm.handle_msg(content['data'])
128 comm.handle_msg(content['data'])
129
129
130 def comm_close(self, stream, ident, msg):
130 def comm_close(self, stream, ident, msg):
131 """Handler for comm_close messages"""
131 """Handler for comm_close messages"""
132 content = msg['content']
132 content = msg['content']
133 comm_id = content['comm_id']
133 comm_id = content['comm_id']
134 comm = self.get_comm(comm_id)
134 comm = self.get_comm(comm_id)
135 if comm is None:
135 if comm is None:
136 # no such comm
136 # no such comm
137 return
137 return
138 comm.handle_close(content['data'])
138 comm.handle_close(content['data'])
139 del self.comms[comm_id]
139 del self.comms[comm_id]
140
140
141
141
142 __all__ = ['CommManager']
142 __all__ = ['CommManager']
General Comments 0
You need to be logged in to leave comments. Login now