Called by IOLoop when the requested timeout has passed.
(self)
| 158 | self._finish_pending_requests() |
| 159 | |
| 160 | def _handle_timeout(self) -> None: |
| 161 | """Called by IOLoop when the requested timeout has passed.""" |
| 162 | self._timeout = None |
| 163 | while True: |
| 164 | try: |
| 165 | ret, num_handles = self._multi.socket_action(pycurl.SOCKET_TIMEOUT, 0) |
| 166 | except pycurl.error as e: |
| 167 | ret = e.args[0] |
| 168 | if ret != pycurl.E_CALL_MULTI_PERFORM: |
| 169 | break |
| 170 | self._finish_pending_requests() |
| 171 | |
| 172 | # In theory, we shouldn't have to do this because curl will |
| 173 | # call _set_timeout whenever the timeout changes. However, |
| 174 | # sometimes after _handle_timeout we will need to reschedule |
| 175 | # immediately even though nothing has changed from curl's |
| 176 | # perspective. This is because when socket_action is |
| 177 | # called with SOCKET_TIMEOUT, libcurl decides internally which |
| 178 | # timeouts need to be processed by using a monotonic clock |
| 179 | # (where available) while tornado uses python's time.time() |
| 180 | # to decide when timeouts have occurred. When those clocks |
| 181 | # disagree on elapsed time (as they will whenever there is an |
| 182 | # NTP adjustment), tornado might call _handle_timeout before |
| 183 | # libcurl is ready. After each timeout, resync the scheduled |
| 184 | # timeout with libcurl's current state. |
| 185 | new_timeout = self._multi.timeout() |
| 186 | if new_timeout >= 0: |
| 187 | self._set_timeout(new_timeout) |
| 188 | |
| 189 | def _handle_force_timeout(self) -> None: |
| 190 | """Called by IOLoop periodically to ask libcurl to process any |
nothing calls this directly
no test coverage detected