Exemple #1
0
    def _handle_timeout(self):
        """Called by IOLoop when the requested timeout has passed."""
        with stack_context.NullContext():
            self._timeout = None
            while True:
                try:
                    ret, num_handles = self._multi.socket_action(
                        pycurl.SOCKET_TIMEOUT, 0)
                except pycurl.error as e:
                    ret = e.args[0]
                if ret != pycurl.E_CALL_MULTI_PERFORM:
                    break
            self._finish_pending_requests()

        # In theory, we shouldn't have to do this because curl will
        # call _set_timeout whenever the timeout changes.  However,
        # sometimes after _handle_timeout we will need to reschedule
        # immediately even though nothing has changed from curl's
        # perspective.  This is because when socket_action is
        # called with SOCKET_TIMEOUT, libcurl decides internally which
        # timeouts need to be processed by using a monotonic clock
        # (where available) while tornado uses python's time.time()
        # to decide when timeouts have occurred.  When those clocks
        # disagree on elapsed time (as they will whenever there is an
        # NTP adjustment), tornado might call _handle_timeout before
        # libcurl is ready.  After each timeout, resync the scheduled
        # timeout with libcurl's current state.
        new_timeout = self._multi.timeout()
        if new_timeout >= 0:
            self._set_timeout(new_timeout)
Exemple #2
0
 def _process_queue(self):
     with stack_context.NullContext():
         while self.queue and len(self.active) < self.max_clients:
             key, request, callback = self.queue.popleft()
             if key not in self.waiting:
                 continue
             self._remove_timeout(key)
             self.active[key] = (request, callback)
             release_callback = functools.partial(self._release_fetch, key)
             self._handle_request(request, release_callback, callback)
Exemple #3
0
    def spawn_callback(self, callback, *args, **kwargs):
        """Calls the given callback on the next IOLoop iteration.

        Unlike all other callback-related methods on IOLoop,
        ``spawn_callback`` does not associate the callback with its caller's
        ``stack_context``, so it is suitable for fire-and-forget callbacks
        that should not interfere with the caller.

        .. versionadded:: 4.0
        """
        with stack_context.NullContext():
            self.add_callback(callback, *args, **kwargs)
Exemple #4
0
 def _handle_force_timeout(self):
     """Called by IOLoop periodically to ask libcurl to process any
     events it may have forgotten about.
     """
     with stack_context.NullContext():
         while True:
             try:
                 ret, num_handles = self._multi.socket_all()
             except pycurl.error as e:
                 ret = e.args[0]
             if ret != pycurl.E_CALL_MULTI_PERFORM:
                 break
         self._finish_pending_requests()
Exemple #5
0
    def _process_queue(self):
        with stack_context.NullContext():
            while True:
                started = 0
                while self._free_list and self._requests:
                    started += 1
                    curl = self._free_list.pop()
                    (request, callback,
                     queue_start_time) = self._requests.popleft()
                    curl.info = {
                        "headers": httputil.HTTPHeaders(),
                        "buffer": BytesIO(),
                        "request": request,
                        "callback": callback,
                        "queue_start_time": queue_start_time,
                        "curl_start_time": time.time(),
                        "curl_start_ioloop_time":
                        self.io_loop.current().time(),
                    }
                    try:
                        self._curl_setup_request(curl, request,
                                                 curl.info["buffer"],
                                                 curl.info["headers"])
                    except Exception as e:
                        # If there was an error in setup, pass it on
                        # to the callback. Note that allowing the
                        # error to escape here will appear to work
                        # most of the time since we are still in the
                        # caller's original stack frame, but when
                        # _process_queue() is called from
                        # _finish_pending_requests the exceptions have
                        # nowhere to go.
                        self._free_list.append(curl)
                        callback(
                            HTTPResponse(request=request, code=599, error=e))
                    else:
                        self._multi.add_handle(curl)

                if not started:
                    break
Exemple #6
0
 def add_callback_from_signal(self, callback, *args, **kwargs):
     with stack_context.NullContext():
         self.add_callback(callback, *args, **kwargs)