##// END OF EJS Templates
s/target/target_name
MinRK -
Show More
@@ -1,173 +1,173 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2013 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // Comm and CommManager bases
10 10 //============================================================================
11 11 /**
12 12 * Base Comm classes
13 13 * @module IPython
14 14 * @namespace IPython
15 15 * @submodule comm
16 16 */
17 17
18 18 var IPython = (function (IPython) {
19 19 "use strict";
20 20
21 21 //-----------------------------------------------------------------------
22 22 // CommManager class
23 23 //-----------------------------------------------------------------------
24 24
25 25 var CommManager = function (kernel) {
26 26 this.comms = {};
27 this.targets = {comm : Comm};
27 this.targets = {};
28 28 if (kernel !== undefined) {
29 29 this.init_kernel(kernel);
30 30 }
31 31 };
32 32
33 33 CommManager.prototype.init_kernel = function (kernel) {
34 34 // connect the kernel, and register message handlers
35 35 this.kernel = kernel;
36 36 var msg_types = ['comm_open', 'comm_msg', 'comm_close'];
37 37 for (var i = 0; i < msg_types.length; i++) {
38 38 var msg_type = msg_types[i];
39 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) {
44 // Register a constructor for a given target key
45 this.targets[target] = constructor;
43 CommManager.prototype.register_target = function (target_name, f) {
44 // Register a target function for a given target name
45 this.targets[target_name] = f;
46 46 };
47 47
48 48 CommManager.prototype.register_comm = function (comm) {
49 49 // Register a comm in the mapping
50 50 this.comms[comm.comm_id] = comm;
51 51 comm.kernel = this.kernel;
52 52 return comm.comm_id;
53 53 };
54 54
55 55 CommManager.prototype.unregister_comm = function (comm_id) {
56 56 // Remove a comm from the mapping
57 57 delete this.comms[comm_id];
58 58 };
59 59
60 60 // comm message handlers
61 61
62 62 CommManager.prototype.comm_open = function (msg) {
63 63 var content = msg.content;
64 var callback = this.targets[content.target];
64 var callback = this.targets[content.target_name];
65 65 if (callback === undefined) {
66 console.log("No such target registered: ", content.target);
66 console.log("No such target registered: ", content.target_name);
67 67 console.log("Available targets are: ", this.targets);
68 68 return;
69 69 }
70 70 var comm = new Comm(content.comm_id);
71 71 this.register_comm(comm);
72 72 callback(comm);
73 73 comm.handle_open(msg);
74 74 };
75 75
76 76 CommManager.prototype.comm_close = function (msg) {
77 77 var content = msg.content;
78 78 var comm = this.comms[content.comm_id];
79 79 if (comm === undefined) {
80 80 return;
81 81 }
82 82 delete this.comms[content.comm_id];
83 83 comm.handle_close(msg);
84 84 };
85 85
86 86 CommManager.prototype.comm_msg = function (msg) {
87 87 var content = msg.content;
88 88 var comm = this.comms[content.comm_id];
89 89 if (comm === undefined) {
90 90 return;
91 91 }
92 92 comm.handle_msg(msg);
93 93 };
94 94
95 95 //-----------------------------------------------------------------------
96 96 // Comm base class
97 97 //-----------------------------------------------------------------------
98 98
99 var Comm = function (comm_id, target) {
99 var Comm = function (comm_id, target_name) {
100 100 this.comm_id = comm_id || new IPython.utils.uuid();
101 this.target = target || 'comm';
101 this.target_name = target_name;
102 102 this._msg_callback = this._open_callback = this._close_callback = null;
103 103 };
104 104
105 105 // methods for sending messages
106 106 Comm.prototype.open = function (data, callbacks) {
107 107 var content = {
108 108 comm_id : this.comm_id,
109 target : this.target,
109 target_name : this.target_name,
110 110 data : data || {},
111 111 };
112 112 return this.kernel.send_shell_message("comm_open", content, callbacks);
113 113 };
114 114
115 115 Comm.prototype.send = function (data, callbacks) {
116 116 var content = {
117 117 comm_id : this.comm_id,
118 118 data : data || {},
119 119 };
120 120 return this.kernel.send_shell_message("comm_msg", content, callbacks);
121 121 };
122 122
123 123 Comm.prototype.close = function (data, callbacks) {
124 124 var content = {
125 125 comm_id : this.comm_id,
126 126 data : data || {},
127 127 };
128 128 return this.kernel.send_shell_message("comm_close", content, callbacks);
129 129 };
130 130
131 131 // methods for registering callbacks for incoming messages
132 132 Comm.prototype._register_callback = function (key, callback) {
133 133 this['_' + key + '_callback'] = callback;
134 134 };
135 135
136 136 Comm.prototype.on_open = function (callback) {
137 137 this._register_callback('open', callback);
138 138 };
139 139
140 140 Comm.prototype.on_msg = function (callback) {
141 141 this._register_callback('msg', callback);
142 142 };
143 143
144 144 Comm.prototype.on_close = function (callback) {
145 145 this._register_callback('close', callback);
146 146 };
147 147
148 148 // methods for handling incoming messages
149 149
150 150 Comm.prototype._maybe_callback = function (key, msg) {
151 151 var callback = this['_' + key + '_callback'];
152 152 if (callback) callback(msg);
153 153 };
154 154
155 155 Comm.prototype.handle_open = function (msg) {
156 156 this._maybe_callback('open', msg);
157 157 };
158 158
159 159 Comm.prototype.handle_msg = function (msg) {
160 160 this._maybe_callback('msg', msg);
161 161 };
162 162
163 163 Comm.prototype.handle_close = function (msg) {
164 164 this._maybe_callback('close', msg);
165 165 };
166 166
167 167 IPython.CommManager = CommManager;
168 168 IPython.Comm = Comm;
169 169
170 170 return IPython;
171 171
172 172 }(IPython));
173 173
@@ -1,150 +1,150 b''
1 1 """Base class for a Comm"""
2 2
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (C) 2013 The IPython Development Team
5 5 #
6 6 # Distributed under the terms of the BSD License. The full license is in
7 7 # the file COPYING, distributed as part of this software.
8 8 #-----------------------------------------------------------------------------
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Imports
12 12 #-----------------------------------------------------------------------------
13 13
14 14 import uuid
15 15
16 16 from IPython.config import LoggingConfigurable
17 17 from IPython.core.getipython import get_ipython
18 18
19 19 from IPython.utils.traitlets import Instance, Unicode, Bytes, Bool, Dict, Any
20 20
21 21 #-----------------------------------------------------------------------------
22 22 # Code
23 23 #-----------------------------------------------------------------------------
24 24
25 25 class Comm(LoggingConfigurable):
26 26
27 27 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
28 28 def _shell_default(self):
29 29 return get_ipython()
30 30
31 31 iopub_socket = Any()
32 32 def _iopub_socket_default(self):
33 33 return self.shell.kernel.iopub_socket
34 34 session = Instance('IPython.kernel.zmq.session.Session')
35 35 def _session_default(self):
36 36 if self.shell is None:
37 37 return
38 38 return self.shell.kernel.session
39 39
40 target = Unicode('comm')
40 target_name = Unicode('comm')
41 41
42 42 topic = Bytes()
43 43 def _topic_default(self):
44 44 return ('comm-%s' % self.comm_id).encode('ascii')
45 45
46 46 _open_data = Dict(help="data dict, if any, to be included in comm_close")
47 47 _close_data = Dict(help="data dict, if any, to be included in comm_close")
48 48
49 49 _open_callback = Any()
50 50 _msg_callback = Any()
51 51 _close_callback = Any()
52 52
53 53 _closed = Bool(False)
54 54 comm_id = Unicode()
55 55 def _comm_id_default(self):
56 56 return uuid.uuid4().hex
57 57
58 58 primary = Bool(True, help="Am I the primary or secondary Comm?")
59 59
60 60 def __init__(self, data=None, **kwargs):
61 61 super(Comm, self).__init__(**kwargs)
62 62 get_ipython().comm_manager.register_comm(self)
63 63 if self.primary:
64 64 # I am primary, open my peer
65 65 self.open(data)
66 66
67 67 def _publish_msg(self, msg_type, data=None, **keys):
68 68 """Helper for sending a comm message on IOPub"""
69 69 data = {} if data is None else data
70 70 self.session.send(self.iopub_socket, msg_type,
71 71 dict(data=data, comm_id=self.comm_id, **keys),
72 72 ident=self.topic,
73 73 )
74 74
75 75 def __del__(self):
76 76 """trigger close on gc"""
77 77 self.close()
78 78
79 79 # publishing messages
80 80
81 81 def open(self, data=None):
82 82 """Open the frontend-side version of this comm"""
83 83 if data is None:
84 84 data = self._open_data
85 self._publish_msg('comm_open', data, target=self.target)
85 self._publish_msg('comm_open', data, target_name=self.target_name)
86 86
87 87 def close(self, data=None):
88 88 """Close the frontend-side version of this comm"""
89 89 if self._closed:
90 90 # only close once
91 91 return
92 92 if data is None:
93 93 data = self._close_data
94 94 self._publish_msg('comm_close', data)
95 95 self._closed = True
96 96
97 97 def send(self, data=None):
98 98 """Send a message to the frontend-side version of this comm"""
99 99 self._publish_msg('comm_msg', data)
100 100
101 101 # registering callbacks
102 102 def on_open(self, callback):
103 103 """Register a callback for comm_open
104 104
105 105 Will be called with the `data` of the open message.
106 106
107 107 Call `on_open(None)` to disable an existing callback.
108 108 """
109 109 self._open_callback = callback
110 110
111 111 def on_close(self, callback):
112 112 """Register a callback for comm_close
113 113
114 114 Will be called with the `data` of the close message.
115 115
116 116 Call `on_close(None)` to disable an existing callback.
117 117 """
118 118 self._close_callback = callback
119 119
120 120 def on_msg(self, callback):
121 121 """Register a callback for comm_msg
122 122
123 123 Will be called with the `data` of any comm_msg messages.
124 124
125 125 Call `on_msg(None)` to disable an existing callback.
126 126 """
127 127 self._msg_callback = callback
128 128
129 129 # handling of incoming messages
130 130
131 131 def handle_open(self, msg):
132 132 """Handle a comm_open message"""
133 133 self.log.debug("handle_open[%s](%s)", self.comm_id, msg)
134 134 if self._open_callback:
135 135 self._open_callback(msg)
136 136
137 137 def handle_close(self, msg):
138 138 """Handle a comm_close message"""
139 139 self.log.debug("handle_close[%s](%s)", self.comm_id, msg)
140 140 if self._close_callback:
141 141 self._close_callback(msg)
142 142
143 143 def handle_msg(self, msg):
144 144 """Handle a comm_msg message"""
145 145 self.log.debug("handle_msg[%s](%s)", self.comm_id, msg)
146 146 if self._msg_callback:
147 147 self._msg_callback(msg)
148 148
149 149
150 150 __all__ = ['Comm']
@@ -1,167 +1,167 b''
1 1 """Base class to manage comms"""
2 2
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (C) 2013 The IPython Development Team
5 5 #
6 6 # Distributed under the terms of the BSD License. The full license is in
7 7 # the file COPYING, distributed as part of this software.
8 8 #-----------------------------------------------------------------------------
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Imports
12 12 #-----------------------------------------------------------------------------
13 13
14 14 import sys
15 15
16 16 from IPython.config import LoggingConfigurable
17 17 from IPython.core.prompts import LazyEvaluate
18 18 from IPython.core.getipython import get_ipython
19 19
20 20 from IPython.utils.importstring import import_item
21 21 from IPython.utils.traitlets import Instance, Unicode, Dict, Any
22 22
23 23 from .comm import Comm
24 24
25 25 #-----------------------------------------------------------------------------
26 26 # Code
27 27 #-----------------------------------------------------------------------------
28 28
29 29 def lazy_keys(dikt):
30 30 """Return lazy-evaluated string representation of a dictionary's keys
31 31
32 32 Key list is only constructed if it will actually be used.
33 33 Used for debug-logging.
34 34 """
35 35 return LazyEvaluate(lambda d: list(d.keys()))
36 36
37 37
38 38 def with_output(method):
39 39 """method decorator for ensuring output is handled properly in a message handler
40 40
41 41 - sets parent header before entering the method
42 42 - publishes busy/idle
43 43 - flushes stdout/stderr after
44 44 """
45 45 def method_with_output(self, stream, ident, msg):
46 46 parent = msg['header']
47 47 self.shell.set_parent(parent)
48 48 self.shell.kernel._publish_status('busy')
49 49 try:
50 50 return method(self, stream, ident, msg)
51 51 finally:
52 52 sys.stdout.flush()
53 53 sys.stderr.flush()
54 54 self.shell.kernel._publish_status('idle')
55 55
56 56 return method_with_output
57 57
58 58
59 59 class CommManager(LoggingConfigurable):
60 60 """Manager for Comms in the Kernel"""
61 61
62 62 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
63 63 def _shell_default(self):
64 64 return get_ipython()
65 65 iopub_socket = Any()
66 66 def _iopub_socket_default(self):
67 67 return self.shell.kernel.iopub_socket
68 68 session = Instance('IPython.kernel.zmq.session.Session')
69 69 def _session_default(self):
70 70 if self.shell is None:
71 71 return
72 72 return self.shell.kernel.session
73 73
74 74 comms = Dict()
75 75 targets = Dict()
76 76
77 77 # Public APIs
78 78
79 def register_target(self, target, f):
80 """Register a callable f for a given target
79 def register_target(self, target_name, f):
80 """Register a callable f for a given target name
81 81
82 82 f will be called with a Comm object as its only argument
83 83 when a comm_open message is received with `target`.
84 84
85 85 f can be a Python callable or an import string for one.
86 86 """
87 87 if isinstance(f, basestring):
88 88 f = import_item(f)
89 89
90 self.targets[target] = f
90 self.targets[target_name] = f
91 91
92 92 def register_comm(self, comm):
93 93 """Register a new comm"""
94 94 comm_id = comm.comm_id
95 95 comm.shell = self.shell
96 96 comm.iopub_socket = self.iopub_socket
97 97 self.comms[comm_id] = comm
98 98 return comm_id
99 99
100 100 def unregister_comm(self, comm_id):
101 101 """Unregister a comm, and close its counterpart"""
102 102 # unlike get_comm, this should raise a KeyError
103 103 comm = self.comms.pop(comm_id)
104 104 comm.close()
105 105
106 106 def get_comm(self, comm_id):
107 107 """Get a comm with a particular id
108 108
109 109 Returns the comm if found, otherwise None.
110 110
111 111 This will not raise an error,
112 112 it will log messages if the comm cannot be found.
113 113 """
114 114 if comm_id not in self.comms:
115 115 self.log.error("No such comm: %s", comm_id)
116 116 self.log.debug("Current comms: %s", lazy_keys(self.comms))
117 117 return
118 118 # call, because we store weakrefs
119 119 comm = self.comms[comm_id]
120 120 return comm
121 121
122 122 # Message handlers
123 123 @with_output
124 124 def comm_open(self, stream, ident, msg):
125 125 """Handler for comm_open messages"""
126 126 content = msg['content']
127 127 comm_id = content['comm_id']
128 target = content['target']
129 callback = self.targets.get(target, None)
128 target_name = content['target_name']
129 f = self.targets.get(target_name, None)
130 130 comm = Comm(comm_id=comm_id,
131 131 shell=self.shell,
132 132 iopub_socket=self.iopub_socket,
133 133 primary=False,
134 134 )
135 if callback is None:
136 self.log.error("No such comm target registered: %s", target)
135 if f is None:
136 self.log.error("No such comm target registered: %s", target_name)
137 137 comm.close()
138 138 return
139 callback(comm)
139 f(comm)
140 140 comm.handle_open(msg)
141 141 self.register_comm(comm)
142 142
143 143 @with_output
144 144 def comm_msg(self, stream, ident, msg):
145 145 """Handler for comm_msg messages"""
146 146 content = msg['content']
147 147 comm_id = content['comm_id']
148 148 comm = self.get_comm(comm_id)
149 149 if comm is None:
150 150 # no such comm
151 151 return
152 152 comm.handle_msg(msg)
153 153
154 154 @with_output
155 155 def comm_close(self, stream, ident, msg):
156 156 """Handler for comm_close messages"""
157 157 content = msg['content']
158 158 comm_id = content['comm_id']
159 159 comm = self.get_comm(comm_id)
160 160 if comm is None:
161 161 # no such comm
162 162 return
163 163 del self.comms[comm_id]
164 164 comm.handle_close(msg)
165 165
166 166
167 167 __all__ = ['CommManager']
General Comments 0
You need to be logged in to leave comments. Login now