Как реализовать таймаут с фрагментированным выводом для дракмы

Drakma в настоящее время не поддерживает тайм-ауты для SBCL, но мне нужен тайм-аут, который возвращает контент, перенесенный до момента времени, когда истек тайм-аут.

Это моя текущая рабочая попытка, но, вероятно, она подходит для thedailywtf вместо производственного кода:

(defun perform-request (url parameters method)
  (let ((string nil))
    (restart-case
        (sb-ext:with-timeout 20
           (let ((stream (drakma:http-request url
                                              :method method
                                              :parameters parameters
                                              :want-stream T)))
             (unwind-protect
                 (do ((char (read-char stream nil nil)
                            (read-char stream nil nil)))
                     (nil nil)
                   (when char 
                     (push char string)))
               (close stream))))
      (ignore ()
        "")
      (default ()
        (coerce (reverse string) 'string)))))

Попытка имеет некоторые серьезные недостатки:

  • метод не может работать короче указанного времени ожидания
  • используя взлом с таймаутом, чтобы вернуться из цикла while-true и убить restart-case чтобы получить соответствующее возвращаемое значение просто чувствует себя неправильно
  • символьное считывание потока вызывает значительную нагрузку на ЦП (вместо того, чтобы просто ждать завершения загрузки и затем выполнять массовое чтение)

Как я могу правильно читать из потока drakma до определенного времени ожидания (или EOF) и затем возвращать чтение в строке?

0 ответов

Другие вопросы по тегам