##// END OF EJS Templates
Fix minor formatting issues
Alex Kramer -
Show More
@@ -1,955 +1,955
1 1 .. _messaging:
2 2
3 3 ======================
4 4 Messaging in IPython
5 5 ======================
6 6
7 7
8 8 Introduction
9 9 ============
10 10
11 11 This document explains the basic communications design and messaging
12 12 specification for how the various IPython objects interact over a network
13 13 transport. The current implementation uses the ZeroMQ_ library for messaging
14 14 within and between hosts.
15 15
16 16 .. Note::
17 17
18 18 This document should be considered the authoritative description of the
19 19 IPython messaging protocol, and all developers are strongly encouraged to
20 20 keep it updated as the implementation evolves, so that we have a single
21 21 common reference for all protocol details.
22 22
23 23 The basic design is explained in the following diagram:
24 24
25 25 .. image:: figs/frontend-kernel.png
26 26 :width: 450px
27 27 :alt: IPython kernel/frontend messaging architecture.
28 28 :align: center
29 29 :target: ../_images/frontend-kernel.png
30 30
31 31 A single kernel can be simultaneously connected to one or more frontends. The
32 32 kernel has three sockets that serve the following functions:
33 33
34 34 1. stdin: this ROUTER socket is connected to all frontends, and it allows
35 35 the kernel to request input from the active frontend when :func:`raw_input` is called.
36 36 The frontend that executed the code has a DEALER socket that acts as a 'virtual keyboard'
37 37 for the kernel while this communication is happening (illustrated in the
38 38 figure by the black outline around the central keyboard). In practice,
39 39 frontends may display such kernel requests using a special input widget or
40 40 otherwise indicating that the user is to type input for the kernel instead
41 41 of normal commands in the frontend.
42 42
43 43 2. Shell: this single ROUTER socket allows multiple incoming connections from
44 44 frontends, and this is the socket where requests for code execution, object
45 45 information, prompts, etc. are made to the kernel by any frontend. The
46 46 communication on this socket is a sequence of request/reply actions from
47 47 each frontend and the kernel.
48 48
49 49 3. IOPub: this socket is the 'broadcast channel' where the kernel publishes all
50 50 side effects (stdout, stderr, etc.) as well as the requests coming from any
51 51 client over the shell socket and its own requests on the stdin socket. There
52 52 are a number of actions in Python which generate side effects: :func:`print`
53 53 writes to ``sys.stdout``, errors generate tracebacks, etc. Additionally, in
54 54 a multi-client scenario, we want all frontends to be able to know what each
55 55 other has sent to the kernel (this can be useful in collaborative scenarios,
56 56 for example). This socket allows both side effects and the information
57 57 about communications taking place with one client over the shell channel
58 58 to be made available to all clients in a uniform manner.
59 59
60 60 All messages are tagged with enough information (details below) for clients
61 61 to know which messages come from their own interaction with the kernel and
62 62 which ones are from other clients, so they can display each type
63 63 appropriately.
64 64
65 65 The actual format of the messages allowed on each of these channels is
66 66 specified below. Messages are dicts of dicts with string keys and values that
67 67 are reasonably representable in JSON. Our current implementation uses JSON
68 68 explicitly as its message format, but this shouldn't be considered a permanent
69 69 feature. As we've discovered that JSON has non-trivial performance issues due
70 70 to excessive copying, we may in the future move to a pure pickle-based raw
71 71 message format. However, it should be possible to easily convert from the raw
72 72 objects to JSON, since we may have non-python clients (e.g. a web frontend).
73 73 As long as it's easy to make a JSON version of the objects that is a faithful
74 74 representation of all the data, we can communicate with such clients.
75 75
76 76 .. Note::
77 77
78 78 Not all of these have yet been fully fleshed out, but the key ones are, see
79 79 kernel and frontend files for actual implementation details.
80 80
81 81 General Message Format
82 82 ======================
83 83
84 84 A message is defined by the following three-dictionary structure::
85 85
86 86 {
87 87 # The message header contains a pair of unique identifiers for the
88 88 # originating session and the actual message id, in addition to the
89 89 # username for the process that generated the message. This is useful in
90 90 # collaborative settings where multiple users may be interacting with the
91 91 # same kernel simultaneously, so that frontends can label the various
92 92 # messages in a meaningful way.
93 93 'header' : {
94 94 'msg_id' : uuid,
95 95 'username' : str,
96 96 'session' : uuid
97 97 # All recognized message type strings are listed below.
98 98 'msg_type' : str,
99 99 },
100 100
101 101 # In a chain of messages, the header from the parent is copied so that
102 102 # clients can track where messages come from.
103 103 'parent_header' : dict,
104 104
105 105 # The actual content of the message must be a dict, whose structure
106 106 # depends on the message type.
107 107 'content' : dict,
108 108 }
109 109
110 110
111 111 Python functional API
112 112 =====================
113 113
114 114 As messages are dicts, they map naturally to a ``func(**kw)`` call form. We
115 115 should develop, at a few key points, functional forms of all the requests that
116 116 take arguments in this manner and automatically construct the necessary dict
117 117 for sending.
118 118
119 119 In addition, the Python implementation of the message specification extends
120 120 messages upon deserialization to the following form for convenience::
121 121
122 122 {
123 123 'header' : dict,
124 124 # The msg's unique identifier and type are always stored in the header,
125 125 # but the Python implementation copies them to the top level.
126 126 'msg_id' : uuid,
127 127 'msg_type' : str,
128 'parent_header' : dict
129 'content' : dict
128 'parent_header' : dict,
129 'content' : dict,
130 130 }
131 131
132 132 All messages sent to or received by any IPython process should have this
133 133 extended structure.
134 134
135 135
136 136 Messages on the shell ROUTER/DEALER sockets
137 137 ===========================================
138 138
139 139 .. _execute:
140 140
141 141 Execute
142 142 -------
143 143
144 144 This message type is used by frontends to ask the kernel to execute code on
145 145 behalf of the user, in a namespace reserved to the user's variables (and thus
146 146 separate from the kernel's own internal code and variables).
147 147
148 148 Message type: ``execute_request``::
149 149
150 150 content = {
151 151 # Source code to be executed by the kernel, one or more lines.
152 152 'code' : str,
153 153
154 154 # A boolean flag which, if True, signals the kernel to execute
155 155 # this code as quietly as possible. This means that the kernel
156 156 # will compile the code with 'exec' instead of 'single' (so
157 157 # sys.displayhook will not fire), and will *not*:
158 158 # - broadcast exceptions on the PUB socket
159 159 # - do any logging
160 160 # - populate any history
161 161 #
162 162 # The default is False.
163 163 'silent' : bool,
164 164
165 165 # A list of variable names from the user's namespace to be retrieved. What
166 166 # returns is a JSON string of the variable's repr(), not a python object.
167 167 'user_variables' : list,
168 168
169 169 # Similarly, a dict mapping names to expressions to be evaluated in the
170 170 # user's dict.
171 171 'user_expressions' : dict,
172 172
173 173 # Some frontends (e.g. the Notebook) do not support stdin requests. If
174 174 # raw_input is called from code executed from such a frontend, a
175 175 # StdinNotImplementedError will be raised.
176 176 'allow_stdin' : True,
177 177
178 178 }
179 179
180 180 The ``code`` field contains a single string (possibly multiline). The kernel
181 181 is responsible for splitting this into one or more independent execution blocks
182 182 and deciding whether to compile these in 'single' or 'exec' mode (see below for
183 183 detailed execution semantics).
184 184
185 185 The ``user_`` fields deserve a detailed explanation. In the past, IPython had
186 186 the notion of a prompt string that allowed arbitrary code to be evaluated, and
187 187 this was put to good use by many in creating prompts that displayed system
188 188 status, path information, and even more esoteric uses like remote instrument
189 189 status aqcuired over the network. But now that IPython has a clean separation
190 190 between the kernel and the clients, the kernel has no prompt knowledge; prompts
191 191 are a frontend-side feature, and it should be even possible for different
192 192 frontends to display different prompts while interacting with the same kernel.
193 193
194 194 The kernel now provides the ability to retrieve data from the user's namespace
195 195 after the execution of the main ``code``, thanks to two fields in the
196 196 ``execute_request`` message:
197 197
198 198 - ``user_variables``: If only variables from the user's namespace are needed, a
199 199 list of variable names can be passed and a dict with these names as keys and
200 200 their :func:`repr()` as values will be returned.
201 201
202 202 - ``user_expressions``: For more complex expressions that require function
203 203 evaluations, a dict can be provided with string keys and arbitrary python
204 204 expressions as values. The return message will contain also a dict with the
205 205 same keys and the :func:`repr()` of the evaluated expressions as value.
206 206
207 207 With this information, frontends can display any status information they wish
208 208 in the form that best suits each frontend (a status line, a popup, inline for a
209 209 terminal, etc).
210 210
211 211 .. Note::
212 212
213 213 In order to obtain the current execution counter for the purposes of
214 214 displaying input prompts, frontends simply make an execution request with an
215 215 empty code string and ``silent=True``.
216 216
217 217 Execution semantics
218 218 ~~~~~~~~~~~~~~~~~~~
219 219
220 220 When the silent flag is false, the execution of use code consists of the
221 221 following phases (in silent mode, only the ``code`` field is executed):
222 222
223 223 1. Run the ``pre_runcode_hook``.
224 224
225 225 2. Execute the ``code`` field, see below for details.
226 226
227 227 3. If #2 succeeds, compute ``user_variables`` and ``user_expressions`` are
228 228 computed. This ensures that any error in the latter don't harm the main
229 229 code execution.
230 230
231 231 4. Call any method registered with :meth:`register_post_execute`.
232 232
233 233 .. warning::
234 234
235 235 The API for running code before/after the main code block is likely to
236 236 change soon. Both the ``pre_runcode_hook`` and the
237 237 :meth:`register_post_execute` are susceptible to modification, as we find a
238 238 consistent model for both.
239 239
240 240 To understand how the ``code`` field is executed, one must know that Python
241 241 code can be compiled in one of three modes (controlled by the ``mode`` argument
242 242 to the :func:`compile` builtin):
243 243
244 244 *single*
245 245 Valid for a single interactive statement (though the source can contain
246 246 multiple lines, such as a for loop). When compiled in this mode, the
247 247 generated bytecode contains special instructions that trigger the calling of
248 248 :func:`sys.displayhook` for any expression in the block that returns a value.
249 249 This means that a single statement can actually produce multiple calls to
250 250 :func:`sys.displayhook`, if for example it contains a loop where each
251 251 iteration computes an unassigned expression would generate 10 calls::
252 252
253 253 for i in range(10):
254 254 i**2
255 255
256 256 *exec*
257 257 An arbitrary amount of source code, this is how modules are compiled.
258 258 :func:`sys.displayhook` is *never* implicitly called.
259 259
260 260 *eval*
261 261 A single expression that returns a value. :func:`sys.displayhook` is *never*
262 262 implicitly called.
263 263
264 264
265 265 The ``code`` field is split into individual blocks each of which is valid for
266 266 execution in 'single' mode, and then:
267 267
268 268 - If there is only a single block: it is executed in 'single' mode.
269 269
270 270 - If there is more than one block:
271 271
272 272 * if the last one is a single line long, run all but the last in 'exec' mode
273 273 and the very last one in 'single' mode. This makes it easy to type simple
274 274 expressions at the end to see computed values.
275 275
276 276 * if the last one is no more than two lines long, run all but the last in
277 277 'exec' mode and the very last one in 'single' mode. This makes it easy to
278 278 type simple expressions at the end to see computed values. - otherwise
279 279 (last one is also multiline), run all in 'exec' mode
280 280
281 281 * otherwise (last one is also multiline), run all in 'exec' mode as a single
282 282 unit.
283 283
284 284 Any error in retrieving the ``user_variables`` or evaluating the
285 285 ``user_expressions`` will result in a simple error message in the return fields
286 286 of the form::
287 287
288 288 [ERROR] ExceptionType: Exception message
289 289
290 290 The user can simply send the same variable name or expression for evaluation to
291 291 see a regular traceback.
292 292
293 293 Errors in any registered post_execute functions are also reported similarly,
294 294 and the failing function is removed from the post_execution set so that it does
295 295 not continue triggering failures.
296 296
297 297 Upon completion of the execution request, the kernel *always* sends a reply,
298 298 with a status code indicating what happened and additional data depending on
299 299 the outcome. See :ref:`below <execution_results>` for the possible return
300 300 codes and associated data.
301 301
302 302
303 303 Execution counter (old prompt number)
304 304 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
305 305
306 306 The kernel has a single, monotonically increasing counter of all execution
307 307 requests that are made with ``silent=False``. This counter is used to populate
308 308 the ``In[n]``, ``Out[n]`` and ``_n`` variables, so clients will likely want to
309 309 display it in some form to the user, which will typically (but not necessarily)
310 310 be done in the prompts. The value of this counter will be returned as the
311 311 ``execution_count`` field of all ``execute_reply`` messages.
312 312
313 313 .. _execution_results:
314 314
315 315 Execution results
316 316 ~~~~~~~~~~~~~~~~~
317 317
318 318 Message type: ``execute_reply``::
319 319
320 320 content = {
321 321 # One of: 'ok' OR 'error' OR 'abort'
322 322 'status' : str,
323 323
324 324 # The global kernel counter that increases by one with each non-silent
325 325 # executed request. This will typically be used by clients to display
326 326 # prompt numbers to the user. If the request was a silent one, this will
327 327 # be the current value of the counter in the kernel.
328 328 'execution_count' : int,
329 329 }
330 330
331 331 When status is 'ok', the following extra fields are present::
332 332
333 333 {
334 334 # 'payload' will be a list of payload dicts.
335 335 # Each execution payload is a dict with string keys that may have been
336 336 # produced by the code being executed. It is retrieved by the kernel at
337 337 # the end of the execution and sent back to the front end, which can take
338 338 # action on it as needed. See main text for further details.
339 339 'payload' : list(dict),
340 340
341 341 # Results for the user_variables and user_expressions.
342 342 'user_variables' : dict,
343 343 'user_expressions' : dict,
344 344 }
345 345
346 346 .. admonition:: Execution payloads
347 347
348 348 The notion of an 'execution payload' is different from a return value of a
349 349 given set of code, which normally is just displayed on the pyout stream
350 350 through the PUB socket. The idea of a payload is to allow special types of
351 351 code, typically magics, to populate a data container in the IPython kernel
352 352 that will be shipped back to the caller via this channel. The kernel
353 353 has an API for this in the PayloadManager::
354 354
355 355 ip.payload_manager.write_payload(payload_dict)
356 356
357 357 which appends a dictionary to the list of payloads.
358 358
359 359
360 360 When status is 'error', the following extra fields are present::
361 361
362 362 {
363 363 'ename' : str, # Exception name, as a string
364 364 'evalue' : str, # Exception value, as a string
365 365
366 366 # The traceback will contain a list of frames, represented each as a
367 367 # string. For now we'll stick to the existing design of ultraTB, which
368 368 # controls exception level of detail statefully. But eventually we'll
369 369 # want to grow into a model where more information is collected and
370 370 # packed into the traceback object, with clients deciding how little or
371 371 # how much of it to unpack. But for now, let's start with a simple list
372 372 # of strings, since that requires only minimal changes to ultratb as
373 373 # written.
374 374 'traceback' : list,
375 375 }
376 376
377 377
378 378 When status is 'abort', there are for now no additional data fields. This
379 379 happens when the kernel was interrupted by a signal.
380 380
381 381 Kernel attribute access
382 382 -----------------------
383 383
384 384 .. warning::
385 385
386 386 This part of the messaging spec is not actually implemented in the kernel
387 387 yet.
388 388
389 389 While this protocol does not specify full RPC access to arbitrary methods of
390 390 the kernel object, the kernel does allow read (and in some cases write) access
391 391 to certain attributes.
392 392
393 393 The policy for which attributes can be read is: any attribute of the kernel, or
394 394 its sub-objects, that belongs to a :class:`Configurable` object and has been
395 395 declared at the class-level with Traits validation, is in principle accessible
396 396 as long as its name does not begin with a leading underscore. The attribute
397 397 itself will have metadata indicating whether it allows remote read and/or write
398 398 access. The message spec follows for attribute read and write requests.
399 399
400 400 Message type: ``getattr_request``::
401 401
402 402 content = {
403 403 # The (possibly dotted) name of the attribute
404 404 'name' : str,
405 405 }
406 406
407 407 When a ``getattr_request`` fails, there are two possible error types:
408 408
409 409 - AttributeError: this type of error was raised when trying to access the
410 410 given name by the kernel itself. This means that the attribute likely
411 411 doesn't exist.
412 412
413 413 - AccessError: the attribute exists but its value is not readable remotely.
414 414
415 415
416 416 Message type: ``getattr_reply``::
417 417
418 418 content = {
419 419 # One of ['ok', 'AttributeError', 'AccessError'].
420 420 'status' : str,
421 421 # If status is 'ok', a JSON object.
422 422 'value' : object,
423 423 }
424 424
425 425 Message type: ``setattr_request``::
426 426
427 427 content = {
428 428 # The (possibly dotted) name of the attribute
429 429 'name' : str,
430 430
431 431 # A JSON-encoded object, that will be validated by the Traits
432 432 # information in the kernel
433 433 'value' : object,
434 434 }
435 435
436 436 When a ``setattr_request`` fails, there are also two possible error types with
437 437 similar meanings as those of the ``getattr_request`` case, but for writing.
438 438
439 439 Message type: ``setattr_reply``::
440 440
441 441 content = {
442 442 # One of ['ok', 'AttributeError', 'AccessError'].
443 443 'status' : str,
444 444 }
445 445
446 446
447 447
448 448 Object information
449 449 ------------------
450 450
451 451 One of IPython's most used capabilities is the introspection of Python objects
452 452 in the user's namespace, typically invoked via the ``?`` and ``??`` characters
453 453 (which in reality are shorthands for the ``%pinfo`` magic). This is used often
454 454 enough that it warrants an explicit message type, especially because frontends
455 455 may want to get object information in response to user keystrokes (like Tab or
456 456 F1) besides from the user explicitly typing code like ``x??``.
457 457
458 458 Message type: ``object_info_request``::
459 459
460 460 content = {
461 461 # The (possibly dotted) name of the object to be searched in all
462 462 # relevant namespaces
463 463 'name' : str,
464 464
465 465 # The level of detail desired. The default (0) is equivalent to typing
466 466 # 'x?' at the prompt, 1 is equivalent to 'x??'.
467 467 'detail_level' : int,
468 468 }
469 469
470 470 The returned information will be a dictionary with keys very similar to the
471 471 field names that IPython prints at the terminal.
472 472
473 473 Message type: ``object_info_reply``::
474 474
475 475 content = {
476 476 # The name the object was requested under
477 477 'name' : str,
478 478
479 479 # Boolean flag indicating whether the named object was found or not. If
480 480 # it's false, all other fields will be empty.
481 481 'found' : bool,
482 482
483 483 # Flags for magics and system aliases
484 484 'ismagic' : bool,
485 485 'isalias' : bool,
486 486
487 487 # The name of the namespace where the object was found ('builtin',
488 488 # 'magics', 'alias', 'interactive', etc.)
489 489 'namespace' : str,
490 490
491 491 # The type name will be type.__name__ for normal Python objects, but it
492 492 # can also be a string like 'Magic function' or 'System alias'
493 493 'type_name' : str,
494 494
495 495 # The string form of the object, possibly truncated for length if
496 496 # detail_level is 0
497 497 'string_form' : str,
498 498
499 499 # For objects with a __class__ attribute this will be set
500 500 'base_class' : str,
501 501
502 502 # For objects with a __len__ attribute this will be set
503 503 'length' : int,
504 504
505 505 # If the object is a function, class or method whose file we can find,
506 506 # we give its full path
507 507 'file' : str,
508 508
509 509 # For pure Python callable objects, we can reconstruct the object
510 510 # definition line which provides its call signature. For convenience this
511 511 # is returned as a single 'definition' field, but below the raw parts that
512 512 # compose it are also returned as the argspec field.
513 513 'definition' : str,
514 514
515 515 # The individual parts that together form the definition string. Clients
516 516 # with rich display capabilities may use this to provide a richer and more
517 517 # precise representation of the definition line (e.g. by highlighting
518 518 # arguments based on the user's cursor position). For non-callable
519 519 # objects, this field is empty.
520 520 'argspec' : { # The names of all the arguments
521 521 args : list,
522 522 # The name of the varargs (*args), if any
523 523 varargs : str,
524 524 # The name of the varkw (**kw), if any
525 525 varkw : str,
526 526 # The values (as strings) of all default arguments. Note
527 527 # that these must be matched *in reverse* with the 'args'
528 528 # list above, since the first positional args have no default
529 529 # value at all.
530 530 defaults : list,
531 531 },
532 532
533 533 # For instances, provide the constructor signature (the definition of
534 534 # the __init__ method):
535 535 'init_definition' : str,
536 536
537 537 # Docstrings: for any object (function, method, module, package) with a
538 538 # docstring, we show it. But in addition, we may provide additional
539 539 # docstrings. For example, for instances we will show the constructor
540 540 # and class docstrings as well, if available.
541 541 'docstring' : str,
542 542
543 543 # For instances, provide the constructor and class docstrings
544 544 'init_docstring' : str,
545 545 'class_docstring' : str,
546 546
547 547 # If it's a callable object whose call method has a separate docstring and
548 548 # definition line:
549 549 'call_def' : str,
550 550 'call_docstring' : str,
551 551
552 552 # If detail_level was 1, we also try to find the source code that
553 553 # defines the object, if possible. The string 'None' will indicate
554 554 # that no source was found.
555 555 'source' : str,
556 556 }
557 '
557
558 558
559 559 Complete
560 560 --------
561 561
562 562 Message type: ``complete_request``::
563 563
564 564 content = {
565 565 # The text to be completed, such as 'a.is'
566 566 'text' : str,
567 567
568 568 # The full line, such as 'print a.is'. This allows completers to
569 569 # make decisions that may require information about more than just the
570 570 # current word.
571 571 'line' : str,
572 572
573 573 # The entire block of text where the line is. This may be useful in the
574 574 # case of multiline completions where more context may be needed. Note: if
575 575 # in practice this field proves unnecessary, remove it to lighten the
576 576 # messages.
577 577
578 578 'block' : str,
579 579
580 580 # The position of the cursor where the user hit 'TAB' on the line.
581 581 'cursor_pos' : int,
582 582 }
583 583
584 584 Message type: ``complete_reply``::
585 585
586 586 content = {
587 587 # The list of all matches to the completion request, such as
588 588 # ['a.isalnum', 'a.isalpha'] for the above example.
589 589 'matches' : list
590 590 }
591 591
592 592
593 593 History
594 594 -------
595 595
596 596 For clients to explicitly request history from a kernel. The kernel has all
597 597 the actual execution history stored in a single location, so clients can
598 598 request it from the kernel when needed.
599 599
600 600 Message type: ``history_request``::
601 601
602 602 content = {
603 603
604 604 # If True, also return output history in the resulting dict.
605 605 'output' : bool,
606 606
607 607 # If True, return the raw input history, else the transformed input.
608 608 'raw' : bool,
609 609
610 610 # So far, this can be 'range', 'tail' or 'search'.
611 611 'hist_access_type' : str,
612 612
613 613 # If hist_access_type is 'range', get a range of input cells. session can
614 614 # be a positive session number, or a negative number to count back from
615 615 # the current session.
616 616 'session' : int,
617 617 # start and stop are line numbers within that session.
618 618 'start' : int,
619 619 'stop' : int,
620 620
621 621 # If hist_access_type is 'tail', get the last n cells.
622 622 'n' : int,
623 623
624 624 # If hist_access_type is 'search', get cells matching the specified glob
625 625 # pattern (with * and ? as wildcards).
626 626 'pattern' : str,
627 627
628 628 }
629 629
630 630 Message type: ``history_reply``::
631 631
632 632 content = {
633 633 # A list of 3 tuples, either:
634 634 # (session, line_number, input) or
635 635 # (session, line_number, (input, output)),
636 636 # depending on whether output was False or True, respectively.
637 637 'history' : list,
638 638 }
639 639
640 640
641 641 Connect
642 642 -------
643 643
644 644 When a client connects to the request/reply socket of the kernel, it can issue
645 645 a connect request to get basic information about the kernel, such as the ports
646 646 the other ZeroMQ sockets are listening on. This allows clients to only have
647 647 to know about a single port (the shell channel) to connect to a kernel.
648 648
649 649 Message type: ``connect_request``::
650 650
651 651 content = {
652 652 }
653 653
654 654 Message type: ``connect_reply``::
655 655
656 656 content = {
657 657 'shell_port' : int # The port the shell ROUTER socket is listening on.
658 658 'iopub_port' : int # The port the PUB socket is listening on.
659 659 'stdin_port' : int # The port the stdin ROUTER socket is listening on.
660 660 'hb_port' : int # The port the heartbeat socket is listening on.
661 661 }
662 662
663 663
664 664
665 665 Kernel shutdown
666 666 ---------------
667 667
668 668 The clients can request the kernel to shut itself down; this is used in
669 669 multiple cases:
670 670
671 671 - when the user chooses to close the client application via a menu or window
672 672 control.
673 673 - when the user types 'exit' or 'quit' (or their uppercase magic equivalents).
674 674 - when the user chooses a GUI method (like the 'Ctrl-C' shortcut in the
675 675 IPythonQt client) to force a kernel restart to get a clean kernel without
676 676 losing client-side state like history or inlined figures.
677 677
678 678 The client sends a shutdown request to the kernel, and once it receives the
679 679 reply message (which is otherwise empty), it can assume that the kernel has
680 680 completed shutdown safely.
681 681
682 682 Upon their own shutdown, client applications will typically execute a last
683 683 minute sanity check and forcefully terminate any kernel that is still alive, to
684 684 avoid leaving stray processes in the user's machine.
685 685
686 686 For both shutdown request and reply, there is no actual content that needs to
687 687 be sent, so the content dict is empty.
688 688
689 689 Message type: ``shutdown_request``::
690 690
691 691 content = {
692 692 'restart' : bool # whether the shutdown is final, or precedes a restart
693 693 }
694 694
695 695 Message type: ``shutdown_reply``::
696 696
697 697 content = {
698 698 'restart' : bool # whether the shutdown is final, or precedes a restart
699 699 }
700 700
701 701 .. Note::
702 702
703 703 When the clients detect a dead kernel thanks to inactivity on the heartbeat
704 704 socket, they simply send a forceful process termination signal, since a dead
705 705 process is unlikely to respond in any useful way to messages.
706 706
707 707
708 708 Messages on the PUB/SUB socket
709 709 ==============================
710 710
711 711 Streams (stdout, stderr, etc)
712 712 ------------------------------
713 713
714 714 Message type: ``stream``::
715 715
716 716 content = {
717 717 # The name of the stream is one of 'stdin', 'stdout', 'stderr'
718 718 'name' : str,
719 719
720 720 # The data is an arbitrary string to be written to that stream
721 721 'data' : str,
722 722 }
723 723
724 724 When a kernel receives a raw_input call, it should also broadcast it on the pub
725 725 socket with the names 'stdin' and 'stdin_reply'. This will allow other clients
726 726 to monitor/display kernel interactions and possibly replay them to their user
727 727 or otherwise expose them.
728 728
729 729 Display Data
730 730 ------------
731 731
732 732 This type of message is used to bring back data that should be diplayed (text,
733 733 html, svg, etc.) in the frontends. This data is published to all frontends.
734 734 Each message can have multiple representations of the data; it is up to the
735 735 frontend to decide which to use and how. A single message should contain all
736 736 possible representations of the same information. Each representation should
737 737 be a JSON'able data structure, and should be a valid MIME type.
738 738
739 739 Some questions remain about this design:
740 740
741 741 * Do we use this message type for pyout/displayhook? Probably not, because
742 742 the displayhook also has to handle the Out prompt display. On the other hand
743 743 we could put that information into the metadata secion.
744 744
745 745 Message type: ``display_data``::
746 746
747 747 content = {
748 748
749 749 # Who create the data
750 750 'source' : str,
751 751
752 752 # The data dict contains key/value pairs, where the kids are MIME
753 753 # types and the values are the raw data of the representation in that
754 754 # format. The data dict must minimally contain the ``text/plain``
755 755 # MIME type which is used as a backup representation.
756 756 'data' : dict,
757 757
758 758 # Any metadata that describes the data
759 759 'metadata' : dict
760 760 }
761 761
762 762 Python inputs
763 763 -------------
764 764
765 765 These messages are the re-broadcast of the ``execute_request``.
766 766
767 767 Message type: ``pyin``::
768 768
769 769 content = {
770 770 'code' : str, # Source code to be executed, one or more lines
771 771
772 772 # The counter for this execution is also provided so that clients can
773 773 # display it, since IPython automatically creates variables called _iN
774 774 # (for input prompt In[N]).
775 775 'execution_count' : int
776 776 }
777 777
778 778 Python outputs
779 779 --------------
780 780
781 781 When Python produces output from code that has been compiled in with the
782 782 'single' flag to :func:`compile`, any expression that produces a value (such as
783 783 ``1+1``) is passed to ``sys.displayhook``, which is a callable that can do with
784 784 this value whatever it wants. The default behavior of ``sys.displayhook`` in
785 785 the Python interactive prompt is to print to ``sys.stdout`` the :func:`repr` of
786 786 the value as long as it is not ``None`` (which isn't printed at all). In our
787 787 case, the kernel instantiates as ``sys.displayhook`` an object which has
788 788 similar behavior, but which instead of printing to stdout, broadcasts these
789 789 values as ``pyout`` messages for clients to display appropriately.
790 790
791 791 IPython's displayhook can handle multiple simultaneous formats depending on its
792 792 configuration. The default pretty-printed repr text is always given with the
793 793 ``data`` entry in this message. Any other formats are provided in the
794 794 ``extra_formats`` list. Frontends are free to display any or all of these
795 795 according to its capabilities. ``extra_formats`` list contains 3-tuples of an ID
796 796 string, a type string, and the data. The ID is unique to the formatter
797 797 implementation that created the data. Frontends will typically ignore the ID
798 798 unless if it has requested a particular formatter. The type string tells the
799 799 frontend how to interpret the data. It is often, but not always a MIME type.
800 800 Frontends should ignore types that it does not understand. The data itself is
801 801 any JSON object and depends on the format. It is often, but not always a string.
802 802
803 803 Message type: ``pyout``::
804 804
805 805 content = {
806 806
807 807 # The counter for this execution is also provided so that clients can
808 808 # display it, since IPython automatically creates variables called _N
809 809 # (for prompt N).
810 810 'execution_count' : int,
811 811
812 812 # The data dict contains key/value pairs, where the kids are MIME
813 813 # types and the values are the raw data of the representation in that
814 814 # format. The data dict must minimally contain the ``text/plain``
815 815 # MIME type which is used as a backup representation.
816 816 'data' : dict,
817 817
818 818 }
819 819
820 820 Python errors
821 821 -------------
822 822
823 823 When an error occurs during code execution
824 824
825 825 Message type: ``pyerr``::
826 826
827 827 content = {
828 828 # Similar content to the execute_reply messages for the 'error' case,
829 829 # except the 'status' field is omitted.
830 830 }
831 831
832 832 Kernel status
833 833 -------------
834 834
835 835 This message type is used by frontends to monitor the status of the kernel.
836 836
837 837 Message type: ``status``::
838 838
839 839 content = {
840 840 # When the kernel starts to execute code, it will enter the 'busy'
841 841 # state and when it finishes, it will enter the 'idle' state.
842 842 execution_state : ('busy', 'idle')
843 843 }
844 844
845 845 Kernel crashes
846 846 --------------
847 847
848 848 When the kernel has an unexpected exception, caught by the last-resort
849 849 sys.excepthook, we should broadcast the crash handler's output before exiting.
850 850 This will allow clients to notice that a kernel died, inform the user and
851 851 propose further actions.
852 852
853 853 Message type: ``crash``::
854 854
855 855 content = {
856 856 # Similarly to the 'error' case for execute_reply messages, this will
857 857 # contain ename, etype and traceback fields.
858 858
859 859 # An additional field with supplementary information such as where to
860 860 # send the crash message
861 861 'info' : str,
862 862 }
863 863
864 864
865 865 Future ideas
866 866 ------------
867 867
868 868 Other potential message types, currently unimplemented, listed below as ideas.
869 869
870 870 Message type: ``file``::
871 871
872 872 content = {
873 873 'path' : 'cool.jpg',
874 874 'mimetype' : str,
875 875 'data' : str,
876 876 }
877 877
878 878
879 879 Messages on the stdin ROUTER/DEALER sockets
880 880 ===========================================
881 881
882 882 This is a socket where the request/reply pattern goes in the opposite direction:
883 883 from the kernel to a *single* frontend, and its purpose is to allow
884 884 ``raw_input`` and similar operations that read from ``sys.stdin`` on the kernel
885 885 to be fulfilled by the client. The request should be made to the frontend that
886 886 made the execution request that prompted ``raw_input`` to be called. For now we
887 887 will keep these messages as simple as possible, since they only mean to convey
888 888 the ``raw_input(prompt)`` call.
889 889
890 890 Message type: ``input_request``::
891 891
892 892 content = { 'prompt' : str }
893 893
894 894 Message type: ``input_reply``::
895 895
896 896 content = { 'value' : str }
897 897
898 898 .. Note::
899 899
900 900 We do not explicitly try to forward the raw ``sys.stdin`` object, because in
901 901 practice the kernel should behave like an interactive program. When a
902 902 program is opened on the console, the keyboard effectively takes over the
903 903 ``stdin`` file descriptor, and it can't be used for raw reading anymore.
904 904 Since the IPython kernel effectively behaves like a console program (albeit
905 905 one whose "keyboard" is actually living in a separate process and
906 906 transported over the zmq connection), raw ``stdin`` isn't expected to be
907 907 available.
908 908
909 909
910 910 Heartbeat for kernels
911 911 =====================
912 912
913 913 Initially we had considered using messages like those above over ZMQ for a
914 914 kernel 'heartbeat' (a way to detect quickly and reliably whether a kernel is
915 915 alive at all, even if it may be busy executing user code). But this has the
916 916 problem that if the kernel is locked inside extension code, it wouldn't execute
917 917 the python heartbeat code. But it turns out that we can implement a basic
918 918 heartbeat with pure ZMQ, without using any Python messaging at all.
919 919
920 920 The monitor sends out a single zmq message (right now, it is a str of the
921 921 monitor's lifetime in seconds), and gets the same message right back, prefixed
922 922 with the zmq identity of the DEALER socket in the heartbeat process. This can be
923 923 a uuid, or even a full message, but there doesn't seem to be a need for packing
924 924 up a message when the sender and receiver are the exact same Python object.
925 925
926 926 The model is this::
927 927
928 928 monitor.send(str(self.lifetime)) # '1.2345678910'
929 929
930 930 and the monitor receives some number of messages of the form::
931 931
932 932 ['uuid-abcd-dead-beef', '1.2345678910']
933 933
934 934 where the first part is the zmq.IDENTITY of the heart's DEALER on the engine, and
935 935 the rest is the message sent by the monitor. No Python code ever has any
936 936 access to the message between the monitor's send, and the monitor's recv.
937 937
938 938
939 939 ToDo
940 940 ====
941 941
942 942 Missing things include:
943 943
944 944 * Important: finish thinking through the payload concept and API.
945 945
946 946 * Important: ensure that we have a good solution for magics like %edit. It's
947 947 likely that with the payload concept we can build a full solution, but not
948 948 100% clear yet.
949 949
950 950 * Finishing the details of the heartbeat protocol.
951 951
952 952 * Signal handling: specify what kind of information kernel should broadcast (or
953 953 not) when it receives signals.
954 954
955 955 .. include:: ../links.rst
General Comments 0
You need to be logged in to leave comments. Login now