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