2014-09-25 36 views
4

我正在尝试在我的小型项目中使用drakma-async。但我无法理解发生了什么。 (我使用emacs + slime + ccl)。我需要用http(s)获取数据并在回调中解析它。我假设我可以得到无法解析的错误数据,所以我想重试。但是,当我试图做一些测试,我只是不明白发生了什么......使用drakma异步和cl异步的不可预知的行为

(defun my-callback (data) 
    (prin1 data) 
    (restart-case 
     (error "Some error parsing data...") 
    (just-continue() (prin1 "Continue...")))) 

(defun simple-test() 
    (let ((future (asf:make-future))) 
    (as:delay #'(lambda() (asf:finish future "Some data")) :time 2) 
    (prin1 (asf:future-finished-p future)) 
    (asf:attach future #'my-callback))) 

(defun drakma-test() 
    (asf:alet ((response (das:http-request "http://www.google.com"))) 
    ;(prin1 (asf:future-finished-p response)) 
    (asf:attach response #'my-callback))) 

(defun drakma-test-let() 
    (let ((response (das:http-request "http://www.google.com"))) 
    ;(prin1 (asf:future-finished-p response)) 
    (asf:attach response #'my-callback))) 

(defun run-test (test) 
    (as:start-event-loop test)) 

1)所以我会这就是我和我的简单的例子(这是我的计划是什么)

? (run-test #'simple-test) 
NIL"Some data" ;I get debugger here with simple-error and choose my restart 
Invoking restart: #<RESTART JUST-CONTINUE #x7F0578EC20AD> 
"Continue..." 
1 

2)这里是我所得到的第二个测试:

? (run-test #'drakma-test) 
"<A LOT OF HTML> 
" 
1 

哪里是我的调试器和我重新开始?

3)取消对;(prin1 (asf:future...))线drakma-test

? (run-test #'drakma-test) 
1 

没有完成/未完成布尔,无数据不打印,我没有得到一个重新开始,我只是得到1作为结果。

4)我假定如果我写(let ((reponse (das:http-request "http://www.google.com"))) ...) instad的(asf:alet ...)response将包含不future对象,但是将阻塞,直到该请求将被完成,response将包含的数据。

? (run-test #'drakma-test-let) 
1 

5)取消对;(prin1 (asf:future...))线drakma-test-let

? (run-test #'drakma-test-let) 
NIL ;future is not finished 
1 

未打印的数据,只是未完成和运行试验的结果。

我已经为cl-async运行了测试,它们都通过了,除了ipv6测试。所以我只是不知道从哪里开始了解发生了什么......为什么我没有调试器并在第二次测试中重新启动?为什么在第三次测试中什么都没有发生(这与第二次相同,但与prin1相同)。为什么在第五次和第五次测试中什么也没发生

P.S.没有足够的信誉为此库创建drakma-asynccl-async标签。我知道drakma-async是建立在drakma,所以我把这个标签。

+1

对于#2,在das:http-request中有一个'future-handler-case',在你看到它之前处理'my-test'的错误。 #3大致是相同的问题:'das:future-finished-p'错误,因为响应是一个字符串而不是未来。在#4中,错误在于'my-test'没有足够的参数,并且因为同样的原因而被隐藏。我不清楚cl-async是否足以说明它是如何工作的。我注意到'(push:future-debug * features *)'让一些错误冒起来了,但你似乎仍然失去了重新启动。 – 2014-09-27 09:50:24

回答

1

感谢m-n的评论,使情况更加清晰,并在短时间内解释了情况。

我做了一些例子,要显示在每一种情况下会发生什么:

例子:

(defun my-callback (&rest data) 
    (format t "Echo from callback: ~A~%" data) 
    (restart-case 
     (error "Some error parsing data...") 
    (just-continue() (prin1 "Continue...")))) 

(defun my-errback (e) 
    (format t "Echo from errback: ~A~%" e)) 

(defun make-example-future() 
    (let ((future (asf:make-future))) ;creating future 
    (as:delay #'(lambda()   ;finishing future in 2 seconds 
        (asf:future-handler-case ;wrapping asf:finish 
        (asf:finish future 
           "Result data") 
        (t (e) (asf:signal-error future e)))) ;signal future an error 
       :time 2) 
    future)) 

(defun simple-test-2() 
    (let ((future (make-example-future))) 
    (format t "Is future?: ~A~%Finished?: ~A~%" 
      (asf:futurep future) (asf:future-finished-p future)) 
    (asf:alet ((result future)) 
     (asf:attach-errback future #'my-errback) 
     (format t "Finished? ~A~%" (asf:future-finished-p future)) 
     (asf:future-finished-p result) 
     (asf:attach result #'my-callback)))) 

,这里是发生了什么:

? (as:start-event-loop #'simple-test-2) 
Is future?: T 
Finished?: NIL 
;<here we have a 2 sec pause> 
Finished? T 
Echo from errback: There is no applicable method for the generic function: 
#<STANDARD-GENERIC-FUNCTION CL-ASYNC-FUTURE:FUTURE-FINISHED-P #x302001B67A8F> 
when called with arguments: 
("Result data") 

A)asf:alet等待结果并将结果值绑定到变量。 所以我错误地认为asf:alet绑定未来。

B)在make-example-future我们总结asf:finishasf:future-handler-case 和使用asf:signal-error发送错误的未来。 这意味着将处理错误并调用errback。 即使稍后在代码中附加回调。 此外,与(asf:future-finished-p result) 的错误处理与future-handler-case,因为它被包装在asf:alet(至少我认为是这样)。

C)注释的(asf:future-finished-p result)并且结果是

Is future?: T 
Finished?: NIL 
Finished? T 
Echo from callback: (Result data) ;here is my data 
Echo from errback: Some error parsing data... ;;here is my error 
1 

drakma-async有类似future-handler-case包装一个包装asf:finish

因此这解释了#2测试结果。我得到的数据和asf:alet返回给我的字符串。来自回调的错误传递给我没有的errback。另外,在drakma-test只使用asf:alet我只是不能附加errback,因为我无法访问未来。我需要在let中拨打http-request,而不是拨打alet

此外,这也解释了#3测试的结果:我收到了发送到errback(future-finished-p)错误。

如果我们看一下#4结果,#5测试新my-callback:可以看出, cl-async尝试调用我的回调与drakma返回的所有值。其中有7个(drakma:http-request返回的值)。 所以我试图附上错误数量的参数回调,我的#4和#5测试发出了一个错误信号,该错误仅由future-hander-case处理并发送到errback

结果: 无论如何,这是因为它发送错误errback可,但失去所有重新启动似乎是不可能的使用与drakma-async无需重启除去future-handler-case

希望这篇文章可以帮助如果有人填满我的问题。