Я использую jet для асинхронного кольцевого адаптера. Jet также поставляется с асинхронным http-клиентом, который возвращает канал, значение которого :body
также является каналом.
Кроме того, обработчик маршрута асинхронного сервера может возвращать карту, ключ :body
которой может содержать канал. Когда этот канал будет закрыт, ответ будет возвращен клиенту.
Я пишу следующий код go
:
(defn- api-call-1 []
(go (-> (jet-client/get "api-url-1")
<!
:body ;; jet http client :body is also a channel.
<!
api-call-1-response-parse)))
(defn- api-call-2 []
(go (-> (jet-client/get "api-url-2")
<!
:body
<!
api-call-2-response-parse)))
(defn route-function []
(let [response-chan (chan)]
(go
(let [api-call-1-chan (api-call-1) ;; using channel returned by go
api-call-2-chan (api-call-2)]
(-> {:api-1 (<! api-call-1-chan)
:api-2 (<! api-call-2-chan)}
encode-response
(>! response-chan)))
(close! response-chan))
;; for not blocking server thread, return channel in body
{:body response-chan :status 200}))
В моем route-function
я не могу заблокировать.
Хотя этот код работает нормально, плохо ли использовать go
в api-call-1?
Я обнаружил, что для использования <!
в api-call-1
мне нужно поместить его в блок go
. Теперь я использую канал этого блока go
в route-function
. Это выглядит унидоматично? Я беспокоюсь о том, чтобы не показывать api-call-1-response-parse
или даже :body
в качестве канала для route-function
.
Как правильно структурировать go
блочный код и функции? Должен ли я заботиться о дополнительных блоках go
в функциях api-call-1/2
?