The receiving end of a cross-interpreter channel.
| 129 | |
| 130 | |
| 131 | class RecvChannel(_ChannelEnd): |
| 132 | """The receiving end of a cross-interpreter channel.""" |
| 133 | |
| 134 | _end = 'recv' |
| 135 | |
| 136 | def recv(self, timeout=None, *, |
| 137 | _sentinel=object(), |
| 138 | _delay=10 / 1000, # 10 milliseconds |
| 139 | ): |
| 140 | """Return the next object from the channel. |
| 141 | |
| 142 | This blocks until an object has been sent, if none have been |
| 143 | sent already. |
| 144 | """ |
| 145 | if timeout is not None: |
| 146 | timeout = int(timeout) |
| 147 | if timeout < 0: |
| 148 | raise ValueError(f'timeout value must be non-negative') |
| 149 | end = time.time() + timeout |
| 150 | obj, unboundop = _channels.recv(self._id, _sentinel) |
| 151 | while obj is _sentinel: |
| 152 | time.sleep(_delay) |
| 153 | if timeout is not None and time.time() >= end: |
| 154 | raise TimeoutError |
| 155 | obj, unboundop = _channels.recv(self._id, _sentinel) |
| 156 | if unboundop is not None: |
| 157 | assert obj is None, repr(obj) |
| 158 | return _resolve_unbound(unboundop) |
| 159 | return obj |
| 160 | |
| 161 | def recv_nowait(self, default=_NOT_SET): |
| 162 | """Return the next object from the channel. |
| 163 | |
| 164 | If none have been sent then return the default if one |
| 165 | is provided or fail with ChannelEmptyError. Otherwise this |
| 166 | is the same as recv(). |
| 167 | """ |
| 168 | if default is _NOT_SET: |
| 169 | obj, unboundop = _channels.recv(self._id) |
| 170 | else: |
| 171 | obj, unboundop = _channels.recv(self._id, default) |
| 172 | if unboundop is not None: |
| 173 | assert obj is None, repr(obj) |
| 174 | return _resolve_unbound(unboundop) |
| 175 | return obj |
| 176 | |
| 177 | def close(self): |
| 178 | _channels.close(self._id, recv=True) |
| 179 | |
| 180 | |
| 181 | class SendChannel(_ChannelEnd): |