2

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)))))

这种尝试确实有一些严重的缺陷:

  • 该方法的运行时间不能短于给定的超时时间
  • 使用带有超时的 hack 从 while-true 循环返回并混蛋restart-case以获得适当的返回值只是感觉不对
  • 流的逐字符读取会导致 CPU 上的大量负载(而不是等待加载完成然后进行批量读取)

如何正确读取 drakma 流直到某个超时(或 EOF),然后返回读取的字符串?

4

0 回答 0