2013-01-12 44 views
9

我很困惑應該如何與胭脂紅進行通話。我發現在carmine's docs描述的wcar宏:胭脂紅的wcar宏應該如何使用?

(defmacro wcar [& body] `(car/with-conn pool spec-server1 [email protected])) 

難道我真的我想談談除了Redis的命令的Redis每次調用wcar?或者我可以在開始時只調用一次嗎?如果是這樣如何?

這是一些代碼tavisrudd的Redis的圖書館看上去像(從我的玩具URL縮短項目的測試套件):

(deftest test_shorten_doesnt_exist_create_new_next 
    (redis/with-server test-server 
    (redis/set "url_counter" 51) 
    (shorten test-url) 
    (is (= "1g" (redis/get (str "urls|" test-url)))) 
    (is (= test-url (redis/get "shorts|1g"))))) 

而現在,我只能把它與胭脂紅通過這樣寫它的工作:

(deftest test_shorten_doesnt_exist_create_new_next 
    (wcar (car/set "url_counter" 51)) 
    (shorten test-url) 
    (is (= "1g" (wcar (car/get (str "urls|" test-url))))) 
    (is (= test-url (wcar (car/get "shorts|1g"))))) 

那麼使用它的正確方式是什麼,以及我沒有得到什麼底層概念?

回答

8

丹的解釋是正確的。

Carmine默認使用響應流水線,而redis-clojure需要你問的流水線,當你想它(使用pipeline宏)。

您希望流水線操作的主要原因是性能。 Redis速度非常快,使用它的瓶頸通常是請求+響應通過網絡傳輸所需的時間。

Clojure destructuring提供了處理流水線響應的一種便捷方式,但它確實需要不同的編寫代碼來redis-clojure。我會寫你的榜樣的方式是這樣的(我假設你shorten FN有副作用,需要GET年代以前被稱爲):

(deftest test_shorten_doesnt_exist_create_new_next 
    (wcar (car/set "url_counter" 51)) 
    (shorten test-url) 
    (let [[response1 response2] (wcar (car/get (str "urls|" test-url)) 
            (car/get "shorts|1g"))] 
    (is (= "1g" response1)) 
    (is (= test-url response2)))) 

所以我們要發送的第一個(SET )向Redis發出請求並等待回覆(我不確定這是否真的有必要)。然後,我們立即發送接下來的兩個請求(GET),允許Redis對響應進行排隊,然後立即接收它們作爲我們要解構的向量。

起初,這可能看起來像是不必要的額外努力,因爲它要求您明確何時接收排隊的響應,但它帶來了很多好處,包括性能,清晰度和composable commands

如果你正在尋找我認爲使用Carmine(只是搜索wcar調用)的例子,我會在GitHub上檢查Touchstone。 (對不起,這是阻止我包括另一個鏈接)。

否則,如果您有任何其他問題,只需要向我發送一封電子郵件(或者提交GitHub問題)。

+0

非常感謝。現在我明白爲什麼這種方法更好,因爲它在連接實際發生時很明顯。 – Oin

5

別擔心,您已經正確使用它了。

Redis請求函數(例如上面使用的get和set)都通過另一個函數send-request!進行路由,該函數依賴於動態綁定的*context*來提供連接。嘗試在沒有該上下文的情況下調用任何這些Redis命令將失敗,並顯示「無上下文」錯誤。 with-conn宏(在wcar中使用)設置該上下文並提供連接。

wcar宏然後只是一個薄的包裝with-conn假設您將使用所有Redis請求相同的連接詳細信息。

到目前爲止,這與Tavis Rudd的redis-clojure的工作原理非常相似。

所以,現在的問題是,爲什麼胭脂紅需要多個wcar's,當Redis-Clojure只需要一個with-server

答案是,事實並非如此。除了有時,當它發生時。胭脂紅的with-conn使用Redis的"Pipelining"發送具有相同連接的多個請求,然後將響應一起打包在一個向量中。自述文件中的示例顯示了這一點。

(wcar (car/ping) 
     (car/set "foo" "bar") 
     (car/get "foo")) 
=> ["PONG" "OK" "bar"] 

在這裏你會看到pingsetget只關心發送請求,留下響應的接收高達wcar。這排除了來自wcar內部的斷言(或任何結果訪問)並導致請求分離以及您擁有的多個wcar調用。

+0

謝謝。有沒有辦法像胭脂紅一樣擁有redis-clojure的功能?即只說每個大塊代碼我想使用哪個redis上下文?就像在測試用例中的例子一樣? – Oin

+0

種。但你可能不滿意它。你可以把所有的斷言放在一個wcar塊裏面。來自Redis的迴應將以wcar形式從矢量形式返回,並且您的斷言將需要採取反對行動。我不能從代碼中知道你的'shorten'函數實現了什麼,但是你應該可以在wcar中運行它(以及任何其他函數)。 –

+0

我應該補充一點,儘管這是可能的,但這並不意味着我推薦它。我真的建議保持wcar範圍儘可能小。 –

相關問題