##// END OF EJS Templates
pass whole message to Comm handlers
MinRK -
Show More
@@ -1,150 +1,150 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2013 The IPython Development Team
2 // Copyright (C) 2013 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // Comm and CommManager bases
9 // Comm and CommManager bases
10 //============================================================================
10 //============================================================================
11 /**
11 /**
12 * Base Comm classes
12 * Base Comm classes
13 * @module IPython
13 * @module IPython
14 * @namespace IPython
14 * @namespace IPython
15 * @submodule comm
15 * @submodule comm
16 */
16 */
17
17
18 var IPython = (function (IPython) {
18 var IPython = (function (IPython) {
19 "use strict";
19 "use strict";
20
20
21 //-----------------------------------------------------------------------
21 //-----------------------------------------------------------------------
22 // CommManager class
22 // CommManager class
23 //-----------------------------------------------------------------------
23 //-----------------------------------------------------------------------
24
24
25 var CommManager = function (kernel) {
25 var CommManager = function (kernel) {
26 this.comms = {};
26 this.comms = {};
27 this.targets = {comm : Comm};
27 this.targets = {comm : Comm};
28 if (kernel !== undefined) {
28 if (kernel !== undefined) {
29 this.init_kernel(kernel);
29 this.init_kernel(kernel);
30 }
30 }
31 };
31 };
32
32
33 CommManager.prototype.init_kernel = function (kernel) {
33 CommManager.prototype.init_kernel = function (kernel) {
34 // connect the kernel, and register message handlers
34 // connect the kernel, and register message handlers
35 this.kernel = kernel;
35 this.kernel = kernel;
36 var msg_types = ['comm_open', 'comm_msg', 'comm_close'];
36 var msg_types = ['comm_open', 'comm_msg', 'comm_close'];
37 for (var i = 0; i < msg_types.length; i++) {
37 for (var i = 0; i < msg_types.length; i++) {
38 var msg_type = msg_types[i];
38 var msg_type = msg_types[i];
39 kernel.register_iopub_handler(msg_type, $.proxy(this[msg_type], this));
39 kernel.register_iopub_handler(msg_type, $.proxy(this[msg_type], this));
40 }
40 }
41 };
41 };
42
42
43 CommManager.prototype.register_target = function (target, constructor) {
43 CommManager.prototype.register_target = function (target, constructor) {
44 // Register a constructor for a given target key
44 // Register a constructor for a given target key
45 this.targets[target] = constructor;
45 this.targets[target] = constructor;
46 };
46 };
47
47
48 CommManager.prototype.register_comm = function (comm) {
48 CommManager.prototype.register_comm = function (comm) {
49 // Register a comm in the mapping
49 // Register a comm in the mapping
50 this.comms[comm.comm_id] = comm;
50 this.comms[comm.comm_id] = comm;
51 comm.kernel = this.kernel;
51 comm.kernel = this.kernel;
52 return comm.comm_id;
52 return comm.comm_id;
53 };
53 };
54
54
55 CommManager.prototype.unregister_comm = function (comm_id) {
55 CommManager.prototype.unregister_comm = function (comm_id) {
56 // Remove a comm from the mapping
56 // Remove a comm from the mapping
57 delete this.comms[comm_id];
57 delete this.comms[comm_id];
58 };
58 };
59
59
60 // comm message handlers
60 // comm message handlers
61
61
62 CommManager.prototype.comm_open = function (msg) {
62 CommManager.prototype.comm_open = function (msg) {
63 var content = msg.content;
63 var content = msg.content;
64 var callback = this.targets[content.target];
64 var callback = this.targets[content.target];
65 if (callback === undefined) {
65 if (callback === undefined) {
66 console.log("No such target registered: ", content.target);
66 console.log("No such target registered: ", content.target);
67 console.log("Available targets are: ", this.targets);
67 console.log("Available targets are: ", this.targets);
68 return;
68 return;
69 }
69 }
70 var comm = new Comm(content.comm_id);
70 var comm = new Comm(content.comm_id);
71 this.register_comm(comm);
71 this.register_comm(comm);
72 callback(comm);
72 callback(comm);
73 comm.handle_open(content.data);
73 comm.handle_open(msg);
74 };
74 };
75
75
76 CommManager.prototype.comm_close = function (msg) {
76 CommManager.prototype.comm_close = function (msg) {
77 var content = msg.content;
77 var content = msg.content;
78 var comm = this.comms[content.comm_id];
78 var comm = this.comms[content.comm_id];
79 if (comm === undefined) {
79 if (comm === undefined) {
80 return;
80 return;
81 }
81 }
82 delete this.comms[content.comm_id];
82 delete this.comms[content.comm_id];
83 comm.handle_close(content.data);
83 comm.handle_close(msg);
84 };
84 };
85
85
86 CommManager.prototype.comm_msg = function (msg) {
86 CommManager.prototype.comm_msg = function (msg) {
87 var content = msg.content;
87 var content = msg.content;
88 var comm = this.comms[content.comm_id];
88 var comm = this.comms[content.comm_id];
89 if (comm === undefined) {
89 if (comm === undefined) {
90 return;
90 return;
91 }
91 }
92 comm.handle_msg(content.data);
92 comm.handle_msg(msg);
93 };
93 };
94
94
95 //-----------------------------------------------------------------------
95 //-----------------------------------------------------------------------
96 // Comm base class
96 // Comm base class
97 //-----------------------------------------------------------------------
97 //-----------------------------------------------------------------------
98
98
99 var Comm = function (comm_id) {
99 var Comm = function (comm_id, target) {
100 this.comm_id = comm_id;
100 this.comm_id = comm_id;
101 this.target = 'comm';
101 this.target = target || 'comm';
102 };
102 };
103
103
104 // methods for sending messages
104 // methods for sending messages
105 Comm.prototype.open = function (data) {
105 Comm.prototype.open = function (data) {
106 var content = {
106 var content = {
107 comm_id : this.comm_id,
107 comm_id : this.comm_id,
108 target : this.target,
108 target : this.target,
109 data : data || {},
109 data : data || {},
110 };
110 };
111 this.kernel.send_shell_message("comm_open", content);
111 this.kernel.send_shell_message("comm_open", content);
112 };
112 };
113
113
114 Comm.prototype.send = function (data) {
114 Comm.prototype.send = function (data) {
115 var content = {
115 var content = {
116 comm_id : this.comm_id,
116 comm_id : this.comm_id,
117 data : data || {},
117 data : data || {},
118 };
118 };
119 return this.kernel.send_shell_message("comm_msg", content);
119 return this.kernel.send_shell_message("comm_msg", content);
120 };
120 };
121
121
122 Comm.prototype.close = function (data) {
122 Comm.prototype.close = function (data) {
123 var content = {
123 var content = {
124 comm_id : this.comm_id,
124 comm_id : this.comm_id,
125 data : data || {},
125 data : data || {},
126 };
126 };
127 return this.kernel.send_shell_message("comm_close", content);
127 return this.kernel.send_shell_message("comm_close", content);
128 };
128 };
129
129
130 // methods for handling incoming messages
130 // methods for handling incoming messages
131
131
132 Comm.prototype.handle_open = function (data) {
132 Comm.prototype.handle_open = function (msg) {
133 $([this]).trigger("comm_open", data);
133 $([this]).trigger("comm_open", msg);
134 };
134 };
135
135
136 Comm.prototype.handle_msg = function (data) {
136 Comm.prototype.handle_msg = function (msg) {
137 $([this]).trigger("comm_msg", data);
137 $([this]).trigger("comm_msg", msg);
138 };
138 };
139
139
140 Comm.prototype.handle_close = function (data) {
140 Comm.prototype.handle_close = function (msg) {
141 $([this]).trigger("comm_close", data);
141 $([this]).trigger("comm_close", msg);
142 };
142 };
143
143
144 IPython.CommManager = CommManager;
144 IPython.CommManager = CommManager;
145 IPython.Comm = Comm;
145 IPython.Comm = Comm;
146
146
147 return IPython;
147 return IPython;
148
148
149 }(IPython));
149 }(IPython));
150
150
@@ -1,152 +1,149 b''
1 """Base class for a Comm"""
1 """Base class for a Comm"""
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 import uuid
14 import uuid
15
15
16 from IPython.config import LoggingConfigurable
16 from IPython.config import LoggingConfigurable
17 from IPython.core.getipython import get_ipython
17 from IPython.core.getipython import get_ipython
18
18
19 from IPython.utils.traitlets import Instance, Unicode, Bytes, Bool, Dict, Any
19 from IPython.utils.traitlets import Instance, Unicode, Bytes, Bool, Dict, Any
20
20
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 # Code
22 # Code
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24
24
25 class Comm(LoggingConfigurable):
25 class Comm(LoggingConfigurable):
26
26
27 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
27 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
28 def _shell_default(self):
28 def _shell_default(self):
29 return get_ipython()
29 return get_ipython()
30 iopub_socket = Any()
30 iopub_socket = Any()
31 def _iopub_socket_default(self):
31 def _iopub_socket_default(self):
32 return self.shell.parent.iopub_socket
32 return self.shell.parent.iopub_socket
33 session = Instance('IPython.kernel.zmq.session.Session')
33 session = Instance('IPython.kernel.zmq.session.Session')
34 def _session_default(self):
34 def _session_default(self):
35 if self.shell is None:
35 if self.shell is None:
36 return
36 return
37 return self.shell.parent.session
37 return self.shell.parent.session
38
38
39 target = Unicode('comm')
39 target = Unicode('comm')
40
40
41 topic = Bytes()
41 topic = Bytes()
42 def _topic_default(self):
42 def _topic_default(self):
43 return ('comm-%s' % self.comm_id).encode('ascii')
43 return ('comm-%s' % self.comm_id).encode('ascii')
44
44
45 _open_data = Dict(help="data dict, if any, to be included in comm_close")
45 _open_data = Dict(help="data dict, if any, to be included in comm_close")
46 _close_data = Dict(help="data dict, if any, to be included in comm_close")
46 _close_data = Dict(help="data dict, if any, to be included in comm_close")
47
47
48 _open_callback = Any()
48 _open_callback = Any()
49 _msg_callback = Any()
49 _msg_callback = Any()
50 _close_callback = Any()
50 _close_callback = Any()
51
51
52 _closed = Bool(False)
52 _closed = Bool(False)
53 comm_id = Unicode()
53 comm_id = Unicode()
54 def _comm_id_default(self):
54 def _comm_id_default(self):
55 return uuid.uuid4().hex
55 return uuid.uuid4().hex
56
56
57 primary = Bool(True, help="Am I the primary or secondary Comm?")
57 primary = Bool(True, help="Am I the primary or secondary Comm?")
58
58
59 def __init__(self, **kwargs):
59 def __init__(self, data=None, **kwargs):
60 super(Comm, self).__init__(**kwargs)
60 super(Comm, self).__init__(**kwargs)
61 get_ipython().comm_manager.register_comm(self)
61 get_ipython().comm_manager.register_comm(self)
62 if self.primary:
62 if self.primary:
63 # I am primary, open my peer
63 # I am primary, open my peer
64 self.open()
64 self.open(data)
65 else:
66 # I am secondary, handle creation
67 self.handle_open(self._open_data)
68
65
69 def _publish_msg(self, msg_type, data=None, **keys):
66 def _publish_msg(self, msg_type, data=None, **keys):
70 """Helper for sending a comm message on IOPub"""
67 """Helper for sending a comm message on IOPub"""
71 data = {} if data is None else data
68 data = {} if data is None else data
72 self.session.send(self.iopub_socket, msg_type,
69 self.session.send(self.iopub_socket, msg_type,
73 dict(data=data, comm_id=self.comm_id, **keys),
70 dict(data=data, comm_id=self.comm_id, **keys),
74 ident=self.topic,
71 ident=self.topic,
75 )
72 )
76
73
77 def __del__(self):
74 def __del__(self):
78 """trigger close on gc"""
75 """trigger close on gc"""
79 self.close()
76 self.close()
80
77
81 # publishing messages
78 # publishing messages
82
79
83 def open(self, data=None):
80 def open(self, data=None):
84 """Open the frontend-side version of this comm"""
81 """Open the frontend-side version of this comm"""
85 if data is None:
82 if data is None:
86 data = self._open_data
83 data = self._open_data
87 self._publish_msg('comm_open', data, target=self.target)
84 self._publish_msg('comm_open', data, target=self.target)
88
85
89 def close(self, data=None):
86 def close(self, data=None):
90 """Close the frontend-side version of this comm"""
87 """Close the frontend-side version of this comm"""
91 if self._closed:
88 if self._closed:
92 # only close once
89 # only close once
93 return
90 return
94 if data is None:
91 if data is None:
95 data = self._close_data
92 data = self._close_data
96 self._publish_msg('comm_close', data)
93 self._publish_msg('comm_close', data)
97 self._closed = True
94 self._closed = True
98
95
99 def send(self, data=None):
96 def send(self, data=None):
100 """Update the frontend-side version of this comm"""
97 """Send a message to the frontend-side version of this comm"""
101 self._publish_msg('comm_msg', data)
98 self._publish_msg('comm_msg', data)
102
99
103 # registering callbacks
100 # registering callbacks
104 def on_open(self, callback):
101 def on_open(self, callback):
105 """Register a callback for comm_open
102 """Register a callback for comm_open
106
103
107 Will be called with the `data` of the open message.
104 Will be called with the `data` of the open message.
108
105
109 Call `on_open(None)` to disable an existing callback.
106 Call `on_open(None)` to disable an existing callback.
110 """
107 """
111 self._open_callback = callback
108 self._open_callback = callback
112
109
113 def on_close(self, callback):
110 def on_close(self, callback):
114 """Register a callback for comm_close
111 """Register a callback for comm_close
115
112
116 Will be called with the `data` of the close message.
113 Will be called with the `data` of the close message.
117
114
118 Call `on_close(None)` to disable an existing callback.
115 Call `on_close(None)` to disable an existing callback.
119 """
116 """
120 self._close_callback = callback
117 self._close_callback = callback
121
118
122 def on_msg(self, callback):
119 def on_msg(self, callback):
123 """Register a callback for comm_msg
120 """Register a callback for comm_msg
124
121
125 Will be called with the `data` of any comm_msg messages.
122 Will be called with the `data` of any comm_msg messages.
126
123
127 Call `on_msg(None)` to disable an existing callback.
124 Call `on_msg(None)` to disable an existing callback.
128 """
125 """
129 self._msg_callback = callback
126 self._msg_callback = callback
130
127
131 # handling of incoming messages
128 # handling of incoming messages
132
129
133 def handle_open(self, data):
130 def handle_open(self, msg):
134 """Handle a comm_open message"""
131 """Handle a comm_open message"""
135 self.log.debug("handle_open[%s](%s)", self.comm_id, data)
132 self.log.debug("handle_open[%s](%s)", self.comm_id, msg)
136 if self._open_callback:
133 if self._open_callback:
137 self._open_callback(data)
134 self._open_callback(msg)
138
135
139 def handle_close(self, data):
136 def handle_close(self, msg):
140 """Handle a comm_close message"""
137 """Handle a comm_close message"""
141 self.log.debug("handle_close[%s](%s)", self.comm_id, data)
138 self.log.debug("handle_close[%s](%s)", self.comm_id, msg)
142 if self._close_callback:
139 if self._close_callback:
143 self._close_callback(data)
140 self._close_callback(msg)
144
141
145 def handle_msg(self, data):
142 def handle_msg(self, msg):
146 """Handle a comm_msg message"""
143 """Handle a comm_msg message"""
147 self.log.debug("handle_msg[%s](%s)", self.comm_id, data)
144 self.log.debug("handle_msg[%s](%s)", self.comm_id, msg)
148 if self._msg_callback:
145 if self._msg_callback:
149 self._msg_callback(data)
146 self._msg_callback(msg)
150
147
151
148
152 __all__ = ['Comm']
149 __all__ = ['Comm']
@@ -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'],
111 primary=False,
110 primary=False,
112 )
111 )
113 if callback is None:
112 if callback is None:
114 self.log.error("No such comm target registered: %s", target)
113 self.log.error("No such comm target registered: %s", target)
115 comm.close()
114 comm.close()
116 return
115 return
117 callback(comm)
116 callback(comm)
117 comm.handle_open(msg)
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(msg)
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'])
139 del self.comms[comm_id]
138 del self.comms[comm_id]
139 comm.handle_close(msg)
140
140
141
141
142 __all__ = ['CommManager']
142 __all__ = ['CommManager']
General Comments 0
You need to be logged in to leave comments. Login now