Как следует использовать макрос carine wcar?
Я смущен тем, как следует делать звонки с кармином. Я нашел wcar
макрос описан в документах Кармина:
(defmacro wcar [& body] `(car/with-conn pool spec-server1 ~@body))
Мне действительно нужно позвонить wcar
каждый раз, когда я хочу поговорить с Redis в дополнение к команде Redis? Или я могу просто назвать это один раз в начале? Если так, как?
Вот как выглядел какой-то код с библиотекой 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")))))
Так как правильно его использовать и какую основную концепцию я не понимаю?
2 ответа
Объяснение Дэна верно.
Carmine
по умолчанию использует конвейеризацию ответов, тогда как redis-clojure
требует от вас запрашивать конвейеризацию, когда вы этого хотите (используя pipeline
макро).
Основная причина, по которой вы хотите конвейерную работу, заключается в производительности. Redis настолько быстр, что узким местом в его использовании часто является время, необходимое для прохождения запроса + ответа по сети.
Деструктуризация Clojure предоставляет удобный способ работы с конвейерным ответом, но требует написания кода иначе redis-clojure
, То, как я написал бы ваш пример, выглядит примерно так (я полагаю, ваш shorten
FN имеет побочные эффекты и должен быть вызван до GET
s):
(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 поставить в очередь ответы, а затем сразу получить их обратно в виде вектора, который мы деструктурируем.
Поначалу это может показаться ненужным дополнительным усилием, поскольку требует, чтобы вы четко указывали, когда следует получать ответы в очереди, но приносит много преимуществ, включая производительность, четкость и возможность составления команд.
Я бы проверил Touchstone на GitHub, если вы ищете пример того, что я считаю идиоматическим Carmine
использовать (просто найдите wcar
звонки). (Извините, ТАК мешает мне включить другую ссылку).
В противном случае просто напишите мне по электронной почте (или подайте заявку на GitHub), если у вас есть другие вопросы.
Не волнуйтесь, вы уже используете это правильно.
Функции запроса Redis (такие как get и set, которые вы используете выше) все направляются через другую функцию send-request!
который опирается на динамически связанный *context*
обеспечить связь. Попытка вызвать любую из этих команд Redis без этого контекста потерпит неудачу с ошибкой "без контекста". with-conn
макрос (используется в wcar
) устанавливает этот контекст и обеспечивает связь.
wcar
макрос тогда просто тонкая обёртка with-conn
сделав предположение, что вы будете использовать одни и те же данные соединения для всех запросов Redis.
Пока что все это очень похоже на то, как работает redis-clojure Тависа Радда.
Итак, теперь вопрос в том, зачем Кармине wcar
когда Redis-Clojure требуется только один with-server
?
И ответ - нет. Помимо иногда, когда это происходит. Кармина with-conn
использует Redis "Pipelining" для отправки нескольких запросов с одним и тем же соединением, а затем упаковывает ответы вместе в вектор. Пример из README показывает это в действии.
(wcar (car/ping)
(car/set "foo" "bar")
(car/get "foo"))
=> ["PONG" "OK" "bar"]
Здесь вы увидите, что ping
, set
а также get
касается только отправки запроса, оставляя получение ответа до wcar
, Это исключает утверждения (или любой доступ к результатам) изнутри wcar и приводит к разделению запросов и множественных wcar
звонки, которые у вас есть.