2014-09-25 41 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

希望這篇文章可以幫助如果有人填滿我的問題。