2013-01-12 2 views
9

나는 카마인 전화를 어떻게해야하는지 혼란 스럽다.카민의 wcar 매크로는 어떻게 사용되어야합니까?

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

난 정말 wcar 내가 레디 스 명령에 추가 레디 스 얘기 할 때마다 전화를해야합니까 : 나는 carmine's docs에 설명 된 매크로 wcar을 발견? 아니면 처음에 한 번만 부를 수 있습니까? 그렇다면 어떻게?

는 tavisrudd의 레디 스 라이브러리 일부 코드가 (내 장난감 단축 URL 프로젝트의있는 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"))))) 

그리고 지금은 오직이처럼 작성하여 카민 작업을 얻을 수 있습니다

(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과 다르게 작성해야합니다.

(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 : 나는 당신의 예를 써서하는 방법은 다음과 같이 (나는 당신의 shorten FN 부작용을 가지고 있으며 GET의 전에 호출 할 필요가 있으리라 믿고있어)입니다) Redis에게 요청하고 답장을 기다리는 것입니다. (실제로 필요한지 확실하지 않습니다.) 다음 두 (GET) 개의 요청을 한 번에 보내면 Redis가 응답을 대기열에 넣은 다음 다시 한꺼번에 수신하여 해체 할 벡터로 만듭니다.

처음에는 대기중인 응답을받는시기를 명시해야하기 때문에 불필요한 노력이 필요할 수도 있지만 성능, 명확성 및 composable commands 등 많은 이점이 있습니다.

내가 관용적 인 Carmine (단지 wcar 호출을 검색)을 사용한다고 생각하는 예를 찾고 있다면 GitHub의 Touchstone을 확인해 볼 것입니다. (죄송합니다. 그래서 내가 다른 링크를 포함하지 못하게하고 있습니다.)

다른 질문이 있으면 그렇지 않으면 이메일을 보내거나 (GitHub 문제를 신고하십시오).

+0

고마워. 이제 연결이 실제로 발생할 때이를 분명하게 보여주기 때문에 왜이 방법이 더 나은지 이해합니다. – Oin

5

걱정하지 마시고 올바른 방법을 사용 중입니다.

Redis 요청 함수 (위에서 사용하는 get 및 set과 같은)는 모두 동적으로 바인딩 된 *context*을 사용하여 연결을 제공하는 다른 함수 send-request!을 통해 라우팅됩니다. 해당 컨텍스트없이 이러한 Redis 명령을 호출하려고하면 "컨텍스트 없음"오류와 함께 실패합니다. with-conn 매크로 (wcar에서 사용)는 해당 컨텍스트를 설정하고 연결을 제공합니다.

wcar 매크로는 모든 Redis 요청에 대해 동일한 연결 세부 정보를 사용한다는 가정하에 with-conn 주위의 단순한 래퍼입니다.

이것은 Tavis Rudd의 redis-clojure 작동 방식과 매우 비슷합니다.

이제 Carmine이 Redis-Clojure가 단일 with-server 만 필요로했을 때 복수 wcar이 필요한 이유가 무엇입니까?

그리고 답은 맞지 않습니다. 때때로 그렇습니다. Carmine의 with-conn은 Redis의 "Pipelining"을 사용하여 동일한 연결로 여러 요청을 보낸 다음 응답을 벡터로 함께 묶습니다. README의 예제는 실제로이를 보여줍니다.

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

은 여기 ping, setget는 요청을 보내는 wcar까지 응답의 수신을 떠나는 것에 만 관심이있는 것을 볼 수 있습니다. 이렇게하면 wcar 내부에서 어설트 (또는 결과 액세스)가 차단되어 요청을 분리하고 여러 번 호출 할 수 있습니다.

+0

감사합니다. 카민과 같은 redis-clojure의 기능과 같은 것을 가질 수있는 방법이 있습니까? 나는. 하나의 큰 코드 블록 당 한 번 사용하고 싶은 redis 문맥 만 말하면됩니까? 테스트 케이스의 예와 같이? – Oin

+0

종류. 그러나 당신은 그것에 만족하지 않을 수도 있습니다. 어설 션을 제외한 모든 것을 wcar 블록 안에 넣을 수 있습니다. Redis의 응답은 벡터의 형태로 wcar에서 반환되며 귀하의 주장은 그에 대응해야합니다. 나는 당신의'단축 '기능이 무엇을 달성하는지 코드에서 알 수는 없지만 당신은 wcar 내부에서 (다른 기능들과 마찬가지로) 그것을 실행하는 것이 좋다. –

+0

나는 이것이 가능할지라도 그것을 추천해야한다는 것을 의미하지는 않는다. 나는 정말로 wcar 범위를 가능한 한 작게 유지할 것을 제안 할 것이다. –