pedestal

ghaskins 2026-04-16T16:57:30.323989Z

@hlship I had a question regarding async + pedestal v0.8.x. Details in thread

ghaskins 2026-04-16T16:59:50.989969Z

In 0.7.0 and earlier, I had a utility library that had a test that had a setup that looked like this

(defn async-endpoint
  [request]
  (go (ring-resp/response "OK")))

(defn routes [port]
  #{["/async" :get (conj [async-interceptor]
                         `async-endpoint)]})
And the async-interceptor (the thing being tested) looked like this
(ns manetu.utils.interceptors
  (:require [clojure.core.async :refer [go <!]]
            [io.pedestal.interceptor :as pedestal]))

(def async-interceptor
  (pedestal/interceptor
   {:name ::async
    :leave (fn [{:keys [response] :as context}]
             (if (instance? clojure.core.async.impl.channels.ManyToManyChannel response)
               (go
                 (assoc context :response (<! response)))
               context))}))

ghaskins 2026-04-16T17:00:44.741449Z

what I noticed is that the cloverage now shows that the

(go
    (assoc context :response (<! response)))
no longer is covered in v0.8.2.

ghaskins 2026-04-16T17:00:57.868069Z

What I wanted to confirm before I make a bad assumption

ghaskins 2026-04-16T17:01:15.750779Z

did 0.8.0 change to basically support async routes?

ghaskins 2026-04-16T17:01:47.552779Z

it seems like it now supports them without my custom interceptor, but I just want to make sure I am not reading it incorrectly and making the wrong adjustments

ghaskins 2026-04-16T17:03:14.364539Z

basically what I see in 0.8.0 is that the (if (instance?) always finds the context is a response map, not a channel…but the test still passes, which suggests that pedestal handled the conversion automatically for me when earlier versions did not

hlship 2026-04-16T17:09:15.585209Z

Your async-endpoint was invalid in Pedestal 0.7. A handler was always synchronous and always returned a response map. https://pedestal.io/pedestal/0.7/reference/interceptors.html#_handlers The fact that your code worked as stated is a bug. If your async-handler hadn't been there to de-reference the core.async channel, you would have seen exceptions further up the interceptor chain as Pedestal code treated the channel as if it were a map. In Pedestal 0.8, handlers can be asynchronous: https://pedestal.io/pedestal/0.8/reference/interceptors.html#handler (it's just a bit subtle, but also mentioned in the change log) The interceptor chain takes care of it, so that your async-interceptor will see the actual response map, once conveyed through the returned channel.

ghaskins 2026-04-16T17:10:57.735219Z

got it, so it was an unsanctioned behavior, but now no longer necessary

ghaskins 2026-04-16T17:11:06.639269Z

thats all I really needed. Ty!

hlship 2026-04-16T17:11:09.256529Z

we aim to please

👍 1