~ubuntu-branches/ubuntu/karmic/pypy/karmic

« back to all changes in this revision

Viewing changes to py/execnet/NOTES

  • Committer: Bazaar Package Importer
  • Author(s): Alexandre Fayolle
  • Date: 2007-04-13 09:33:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070413093309-yoojh4jcoocu2krz
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
=============================================================================
 
2
                      Channel implementation notes
 
3
=============================================================================
 
4
 
 
5
 
 
6
The public API of channels make them appear either opened or closed.
 
7
When a channel is closed, we can't send any more items, and it will not
 
8
receive any more items than already queued.
 
9
 
 
10
Callbacks make the situation slightly more subtle.  Callbacks are
 
11
attached to the ChannelFactory object, so that Channel objects can be
 
12
garbage-collected and still leave behind an active callback that can
 
13
continue to receive items.
 
14
 
 
15
The CHANNEL_CLOSE message is sent when a channel id is about to be removed
 
16
from the ChannelFactory, which means when the Channel object has been
 
17
garbage-collected *and* there is no callback any more.
 
18
 
 
19
If a Channel object is garbage-collected but the ChannelFactory has a
 
20
callback for it, a CHANNEL_LAST_MESSAGE message is sent.  It is only useful
 
21
if both sides' Channel objects have an associated callback.  In this
 
22
situation, CHANNEL_LAST_MESSAGE allows its receiver to un-register its own
 
23
callback; if/when in addition the receiver side also looses the last
 
24
reference to its Channel object, the Channel is closed.  So in this particular
 
25
situation both sides must forget about the Channel object for it to be
 
26
automatically closed.
 
27
 
 
28
 
 
29
 
 
30
gateway   <--->    channelfactory ---> {id: weakref(channel)}
 
31
                                  ---> {id: callback}
 
32
 
 
33
 
 
34
 
 
35
State and invariants of Channel objects
 
36
---------------------------------------
 
37
 
 
38
_channels and _callbacks are dictionaries on the ChannelFactory.
 
39
Other attributes are on the Channel objects.
 
40
 
 
41
All states are valid at any time (even with multithreading) unless
 
42
marked with {E}, which means that they may be temporary invalid.
 
43
They are eventually restored.
 
44
 
 
45
 
 
46
States ("sendonly" means opened but won't receive any more items):
 
47
 
 
48
  opened               sendonly          closed                deleted
 
49
 =================    ==============    ==================    ===============
 
50
  not _closed          not _closed       _closed               <no ref left>
 
51
  not _receiveclosed   _receiveclosed    {E} _receiveclosed
 
52
 
 
53
In the presence of callbacks, "deleted" does not imply "closed" nor "sendonly".
 
54
It only means that no more items can be sent.  The (logical) channel can
 
55
continue to receive data via the call-back even if the channel object no
 
56
longer exists.
 
57
 
 
58
 
 
59
The two kinds of channels, with or without callback:
 
60
 
 
61
   items read by receive()           has a callback
 
62
  =============================     =======================================
 
63
   _items is a Queue                 _items is None
 
64
   id not in _callbacks
 
65
                                     state==opened: id in _callbacks
 
66
   {E} state==sendonly: there is     {E} state!=opened: id not in _callbacks
 
67
         an ENDMARKER in _items
 
68
   {E} state==closed: there is
 
69
         an ENDMARKER in _items
 
70
 
 
71
Callback calls should be considered asynchronuous.  The channel can be in any
 
72
state and change its state while the callback runs.
 
73
 
 
74
 
 
75
The ChannelFactory's WeakValueDictionary _channels maps some ids to their
 
76
channel object, depending on their state:
 
77
 
 
78
  opened               sendonly          closed              deleted
 
79
 =================    ==============    ================    ===============
 
80
  id in _channels      {E} not in        {E} not in          not in
 
81
 
 
82
 
 
83
All received RemoteErrors are handled exactly once: they are normally
 
84
re-raised once in waitclose() or receive().  If it is not possible, they are
 
85
at the moment dumped to stderr.  (XXX should use logging/tracing)
 
86
Only channels in {E} "closed" state can hold RemoteErrors.
 
87
 
 
88
 
 
89
Methods:
 
90
 
 
91
 * close()      returns with the channel in "closed" state
 
92
 * send()       either send the data or raise if "closed"
 
93
 * receive()    wait for the next item.  If no item left and the state
 
94
                   changes to non-"opened", raise
 
95
 * waitclose()  wait for a non-"opened" state
 
96
 
 
97
 
 
98
Assuming the channel is connected and the connection is alive, the local state
 
99
eventually influences the state of the corresponding remote channel object:
 
100
 
 
101
    local |   opened    sendonly    closed    deleted
 
102
remote    |
 
103
=======================================================
 
104
          |
 
105
   opened |     ok         n/a        (1)       (2)
 
106
          |
 
107
 sendonly |     n/a        n/a        n/a       ok
 
108
          |
 
109
   closed |     (1)        n/a        ok        ok
 
110
          |
 
111
  deleted |     (2)        ok         ok        ok
 
112
 
 
113
(1)  The side with the closed channel object must send a CHANNEL_CLOSE message,
 
114
     which will eventually put the other side's channel in "closed" state if
 
115
     it is still "opened".
 
116
 
 
117
(2)  If the deleted channel has no callback, this is equivalent to (1).
 
118
     Otherwide, the side with the deleted channel must send a
 
119
     CHANNEL_LAST_MESSAGE, which will eventually put the other side's channel in
 
120
     "sendonly" state if it is still "opened".
 
121
 
 
122
n/a  These configuration should never occur.