title: Clojure - use a core.async channel with Yada/Aleph
body: <p>I am trying to use Clojure <a href="https://github.com/ztellman/manifold" rel="nofollow"><code>manifold</code></a> library, and in order to understand it, I need wanted to convert a <a href="https://github.com/clojure/core.async" rel="nofollow"><code>core.async</code></a> channel into a manifold stream.</p>
  
  <p>I would like to create the equivalent the following using a <code>core.async</code> channel :</p>
  
  <pre><code> (require '[manifold.stream :as s])
   (s/periodically 100 #(str " ok "))
  
    ;; Here is what I tried, it fails with an error 500
    (let [ch (chan)]
        (go-loop []
        (&gt;! ch " ok ")
        (&lt;! (timeout 100))
        (recur))
      (s/-&gt;source ch))
  </code></pre>
  
  <p>I am trying to feed a <code>core.async</code> channel into <a href="https://github.com/juxt/yada" rel="nofollow"><code>yada</code></a>. The first code sample, using <code>manifold.stream/periodic</code> works, not the others using <code>core.async</code>. I tried on yada <code>1.0.0</code> and <code>1.1.0-SNAPSHOT</code>.</p>
  
  <p>Using <code>manifold.stream/periodic</code> works :</p>
  
  <pre><code>(def get-stream
    (yada (fn [ctx]
            (-&gt; (:response ctx)
                (assoc :status 202)
                (assoc :body (s/periodically 1000 #(str (System/currentTimeMillis) " ")))))
          {:representations [{:media-type "application/json"
                              :charset    "UTF-8"}
                             {:media-type "application/edn"
                              :charset    "UTF-8"}]}))
  </code></pre>
  
  <p>Using <code>manifold.stream/-&gt;source</code> returns an error 500 :</p>
  
  <pre><code>(def get-stream
    (yada (fn [ctx]
            (-&gt; (:response ctx)
                (assoc :status 202)
                ;; Similar to this : https://github.com/juxt/yada/blob/94f3ee93de155a8513b27e0508608691ed556a55/dev/src/yada/dev/async.clj
                (assoc :body (let [ch (chan)]
                               (go-loop []
                                 (&gt;! ch " ok ")
                                 (&lt;! (timeout 100))
                                 (recur))
                               (s/-&gt;source ch)))))
          {:representations [{:media-type "application/json"
                              :charset    "UTF-8"}
                             {:media-type "application/edn"
                              :charset    "UTF-8"}]}))
  
  ;; Error on the page :
  
  ;; 500: Unknown
  ;; Error on GET
  
  ;; #error {
  ;;         :cause "No implementation of method: :to-body of protocol: #'yada.body/MessageBody found for class: manifold.stream.async.CoreAsyncSource"
  ;;         :via
  ;;         [{:type clojure.lang.ExceptionInfo
  ;;           :message "Error on GET"
  ;;           :data {:response #yada.response.Response{:representation {:media-type #yada.media-type[application/json;q=1.0], :charset #yada.charset.CharsetMap{:alias "UTF-8", :quality 1.0}}, :vary #{:media-type}}, :resource #function[backend.routes.examples.ts/fn--57734]}
  ;;                                                                                                  :at [clojure.core$ex_info invoke "core.clj" 4593]}
  ;;                                                                     {:type java.lang.IllegalArgumentException
  ;;                                                                      :message "No implementation of method: :to-body of protocol: #'yada.body/MessageBody found for class: manifold.stream.async.CoreAsyncSource"
  ;;                                                                      :at [clojure.core$_cache_protocol_fn invoke "core_deftype.clj" 554]}]
  ;;                                                    :trace
  </code></pre>
  
  <p>Third attempt, with a <code>core.async</code> channel (different error 500) :</p>
  
  <pre><code>(def get-stream
    (yada (fn [ctx]
            (-&gt; (:response ctx)
            (assoc :status 202)
            (assoc :body (chan)))
          {:representations [{:media-type "application/json"
                              :charset    "UTF-8"}
                             {:media-type "application/edn"
                              :charset    "UTF-8"}]}))
  
  ;; Error on the page :
  
  ;; 500: Unknown
  
  ;; Error on GET
  
  ;; #error {
  ;;         :cause "No implementation of method: :to-body of protocol: #'yada.body/MessageBody found for class: clojure.core.async.impl.channels.ManyToManyChannel"
  ;;         :via
  ;;         [{:type clojure.lang.ExceptionInfo
  ;;           :message "Error on GET"
  ;;           :data {:response #yada.response.Response{:representation {:media-type #yada.media-type[application/json;q=1.0], :charset #yada.charset.CharsetMap{:alias "UTF-8", :quality 1.0}}, :vary #{:media-type}}, :resource #function[backend.routes.api.subscribe/subscribe$fn--64130]}
  ;;                                                                                                  :at [clojure.core$ex_info invoke "core.clj" 4593]}
  ;;                                                                     {:type java.lang.IllegalArgumentException
  ;;                                                                      :message "No implementation of method: :to-body of protocol: #'yada.body/MessageBody found for class: clojure.core.async.impl.channels.ManyToManyChannel"
  ;;                                                                      :at [clojure.core$_cache_protocol_fn invoke "core_deftype.clj" 554]}]
  ;;                                                    :trace
  </code></pre>