Структурирование кода clojure с помощью блоков go

Я использую 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?


person Ashish Negi    schedule 21.03.2016    source источник


Ответы (1)


То, что у вас есть, очень похоже на эквивалентный код, который у меня есть в производстве. Это довольно идиоматично, поэтому я думаю, что ваш код структурирован правильно.

Тот факт, что операции парковки core.async не могут пересекать границы функций, связан с тем, что он написан как макрос и должен обрабатывать весь фрагмент кода сразу (или, по крайней мере, пока он лексически доступен). Это приводит к тому, что весь код core.async выводится в соответствии с используемым вами шаблоном.

person Arthur Ulfeldt    schedule 21.03.2016