1
\$\begingroup\$

I need to retrieve two files that are labeled :abi and :bin from a server. I then want to add these files to a database in a method with a signature like (q/upsert-contract <abi> <bin>).

To do this I used core.async and wrote the following code:

(defn fetch-contract-code [contract-key code-type]
  (let [result-chan (async/chan)
        handler     (fn [[ok data]]
                      (if ok
                        (go (async/>! result-chan {code-type data})
                            (async/close! result-chan))
                        (println "error fetching" contract-key)))
        request     {:method          :get
                     :uri             (string/format "./contracts/build/%s.%s"
                                                     (name contract-key)
                                                     (name code-type))
                     :timeout         6000
                     :response-format (if (= code-type :abi)
                                        (ajax/json-response-format)
                                        (ajax/text-response-format))
                     :handler         handler}]
    (ajax/ajax-request request)
    result-chan))


(defn add-compiled-contract
  "Retrieve :abi or :bin of smart contract with contract-key and store in db"
  [contract-key]
  (go (let [result-chans      (map (partial fetch-contract-code contract-key) [:abi :bin])
            {:keys [abi bin]} (async/<!
                               (go-loop [acc {} chans result-chans]
                                 (let [c (first chans)]
                                   (if c
                                     (recur (merge acc (async/<! c))
                                            (next chans))
                                     acc))))]
        (q/upsert-contract contract-key abi bin))))

So it returns core.async channels with the data on it in fetch-contract-code (labeling it with either :abi or :bin), and it is retrieved in add-compiled-contract later.

What I find ugly is that everything is returning channels, and I have to get data from all channels. I have a feeling things can be cleaned up, but I don't know how.

Could someone help me cleaning up the following code? Perhaps by using transducers? Or outside of the box thinking?

\$\endgroup\$
  • 1
    \$\begingroup\$ wondered for a sec, why you'd add diminuitive suffixes to result, until I noticed you're not actually using keigo ... \$\endgroup\$ – Vogel612 Jul 5 '17 at 21:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.