如何使用胭脂红的wcar宏?

Oin*_*Oin 10 clojure redis carmine

我对如何使用胭脂红进行调用感到困惑.我wcarcarmine的文档中找到了描述的宏:

(defmacro wcar [& body] `(car/with-conn pool spec-server1 ~@body))
Run Code Online (Sandbox Code Playgroud)

wcar除了redis命令之外,每次我想和redis交谈时,我是否真的需要打电话?或者我可以在开始时调用一次吗?如果是这样的话?

这是tavisrudd的redis库中的一些代码看起来像(来自我的玩具url shortener项目的testsuite):

(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")))))
Run Code Online (Sandbox Code Playgroud)

而现在我只能通过这样编写来使用胭脂红:

(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")))))
Run Code Online (Sandbox Code Playgroud)

那么使用它的正确方法是什么?我没有得到什么基本概念?

小智 9

丹的解释是正确的.

Carmine默认情况下使用响应流水线,而redis-clojure要求您在需要时请求流水线操作(使用pipeline宏).

您想要流水线操作的主要原因是性能.Redis速度非常快,以至于使用它的瓶颈通常是请求+响应通过网络传输所需的时间.

Clojure解构提供了一种处理流水线响应的便捷方法,但它确实需要以不同的方式编写代码redis-clojure.我写你的例子的方式是这样的(我假设你的shortenfn有副作用,需要在GETs 之前调用):

(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))))
Run Code Online (Sandbox Code Playgroud)

所以我们将第一个(SET)请求发送给Redis并等待回复(我不确定这是否真的有必要).然后我们立即发送下两个(GET)请求,允许Redis对响应进行排队,然后立即将它们全部作为我们将要解构的向量接收.

起初,这似乎是不必要的额外努力,因为它要求您明确何时接收排队响应,但它带来了许多好处,包括性能,清晰度和可组合命令.

如果你正在寻找一个我认为惯用的例子Carmine(只是搜索wcar电话),我会在GitHub上查看Touchstone .(抱歉,SO阻止我包含其他链接).

否则,如果您有任何其他问题,只需给我发电子邮件(或提交GitHub问题).


Dan*_*ood 6

别担心,你已经以正确的方式使用它了.

Redis请求函数(例如您上面使用的get和set)都通过另一个send-request!依赖动态绑定*context*提供连接的函数进行路由.尝试在没有该上下文的情况下调用任何这些Redis命令将失败,并显示"无上下文"错误.的with-conn宏(在使用wcar)设置一个上下文,并提供该连接.

然后,wcar宏只是一个薄的包装器with-conn,假设您将对所有Redis请求使用相同的连接详细信息.

到目前为止,这与Tavis Rudd的redis-clojure的工作方式非常相似.

那么,现在的问题是为什么wcar当Redis-Clojure只需要一个单独的时候Carmine需要多个with-server

答案是,它没有.除了有时,它确实如此.Carmine with-conn使用Redis的"Pipelining"以相同的连接发送多个请求,然后将响应打包在一个向量中.README中的示例显示了这一点.

(wcar (car/ping)
      (car/set "foo" "bar")
      (car/get "foo"))
=> ["PONG" "OK" "bar"]
Run Code Online (Sandbox Code Playgroud)

在这里,您将看到ping,set并且get只关注发送请求,接收响应wcar.这会阻止来自wcar内部的断言(或任何结果访问),并导致请求与wcar您拥有的多个呼叫分离.