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),然后返回读取的字符串?