I'm working on reitit http application which uses interceptors.
Below is my code
(ns ic.reitit-interceptor-multithreading)
(require '[reitit.ring :as ring])
(require '[reitit.http :as http])
(require '[reitit.interceptor.sieppari :as sieppari])
(require '[clojure.core.async :refer [go]])
(defn interceptor [number]
{:enter (fn [ctx]
(go
(println "in enter interceptor" number (.getName (Thread/currentThread)))
(update-in ctx [:request :number] (fnil + 0) number)))})
(def app
(http/ring-handler
(http/router
["/api"
{:interceptors [(interceptor 1)]}
["/number"
{:interceptors [(interceptor 10)]
:get {:interceptors [(interceptor 100)]
:handler (fn [req]
(println "in handler")
{:status 200
:body (select-keys req [:number])})}}]])
;; the default handler
(ring/create-default-handler)
;; executor
{:executor sieppari/executor}))
When I'm executing the code in repl I get error -
(require '[ic.reitit-interceptor-multithreading :refer :all])
(app {:request-method :get, :uri "/api/number"})
The error I get is -
Loading src/ic/reitit_interceptor_multithreading.clj... done (app {:request-method :get, :uri "/api/number"}) Execution error (ExceptionInfo) at sieppari.core/-invalid-context-type! (core.cljc:34). Unsupported Context on :enter - clojure.core.async.impl.channels.ManyToManyChannel@4abe39b8 in enter interceptor 1 async-dispatch-3
When I remove go
macro from interceptor enter function then it is working fine.
How can I fix this issue?
Try to add [sieppari.async.core-async :as ca]
into ns
definition:
(ns ic.reitit-interceptor-multithreading
(:require
[reitit.ring :as ring]
[reitit.http :as http]
[reitit.interceptor.sieppari :as sieppari]
[clojure.core.async :refer [go]]
[sieppari.async.core-async :as ca])
(:gen-class))
Then call (app {:request-method :get, :uri "/api/number"})
again.
Maybe there is an easier way, so here is full explanation:
Look into a stack trace and see, which functions are called:
Interceptor has to return context map (c/context?
) or async channel (a/async?
). go
should return the async channel, so you will look for async?
definition. async?
is a method of AsyncContext
protocol and returns false
for any object. sieppari/async/core_async.cljc extends this protocol to async channels, which should return true
.