This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-11-25
Channels
- # announcements (8)
- # babashka (58)
- # beginners (59)
- # biff (4)
- # calva (39)
- # cider (2)
- # clj-kondo (8)
- # clj-together (4)
- # cljdoc (5)
- # cljsrn (1)
- # clojure (60)
- # clojure-australia (2)
- # clojure-europe (16)
- # clojure-nl (1)
- # clojure-norway (3)
- # clojurescript (13)
- # conjure (10)
- # cursive (9)
- # datomic (5)
- # dev-tooling (1)
- # emacs (6)
- # events (1)
- # graalvm (38)
- # graphql (5)
- # joyride (1)
- # kaocha (3)
- # lsp (23)
- # malli (2)
- # mount (2)
- # off-topic (31)
- # other-languages (13)
- # pathom (3)
- # polylith (12)
- # portal (4)
- # practicalli (22)
- # re-frame (6)
- # reagent (3)
- # releases (3)
- # sql (4)
- # squint (3)
- # tools-build (10)
- # tools-deps (10)
- # xtdb (4)
It looks like Lacinia will always execute all the resolvers in a different thread than the caller, even if no async is ever into play - is there a reason for this other than implementation simplicity? It doesn't play well with ThreadLocals, and I can't see a clear way to inject some ThreadLocals into the executing thread...
Ah, I see that Lacinia 1.2 alpha provides an executor option that will be useful - trying this out
It works just fine:
(defn lacinia-executor
"An Executor that will carefully copy the Log4J2 context into the running thread,
clearing it out before/after execution. This will copy Log4J2 context variables
into the ThreadLocal of the executing resolvers, helping with logging and Sentry reports."
[]
(let [queue (LinkedBlockingQueue.)
*thread-id (atom 0)
^ThreadFactory factory (reify ThreadFactory
(^Thread newThread [_ ^Runnable runnable]
(Thread. runnable
(format "GraphQL Executor #%d" (swap! *thread-id inc)))))
executor (proxy [ThreadPoolExecutor]
[(int 0) (int 10)
1 TimeUnit/SECONDS
queue
factory]
(execute [^Runnable r]
(let [ctx (org.apache.logging.log4j.ThreadContext/getImmutableContext)
r' (fn []
(org.apache.logging.log4j.ThreadContext/putAll ctx)
(.run r))]
(proxy-super execute r')))
(beforeExecute [^Thread t ^Runnable e]
(org.apache.logging.log4j.ThreadContext/clearMap)
(proxy-super beforeExecute t e))
(afterExecute [^Thread t ^Runnable e]
(proxy-super afterExecute t e)
(org.apache.logging.log4j.ThreadContext/clearMap)))]
executor))
👍 2