Created
May 4, 2017 22:21
-
-
Save crimeminister/14d87055b893cb1c0c11dd3eb5f84458 to your computer and use it in GitHub Desktop.
Pedestal "prequeue" utility method for prepending interceptors to the interceptor chain
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; This is a snippet of code I used to prepend interceptors to the Pedestal interceptor chain. | |
;; It was written because of a situation in which I had to be sure that the added interceptors | |
;; executed immediately after the current interceptor. Would there be any interest in a PR to | |
;; add this to Pedestal, possible with a different API? E.g. instead of (prequeue) I could alter | |
;; the (chain/enqueue) function to accept a :location argument: | |
;; | |
;; (enqueue :location :front) | |
;; (enqueue :location :back) | |
;; (enqueue :location :after some-other-interceptor) | |
(ns foobar.core | |
(:require | |
[io.pedestal.interceptor :as interceptor] | |
[io.pedestal.interceptor.chain :as chain] | |
[io.pedestal.log :as log])) | |
(defn- pq->vec | |
[persistent-queue] | |
{:pre [(or (nil? persistent-queue) | |
(instance? clojure.lang.PersistentQueue persistent-queue))]} | |
(loop [pq persistent-queue | |
acc []] | |
(let [val (peek pq)] | |
(if (nil? val) | |
acc | |
(recur (pop pq) (conj acc val)))))) | |
(defn- pq-prepend | |
[pq v] | |
{:pre [(or (nil? pq) | |
(instance? clojure.lang.PersistentQueue pq)) | |
(seq? v)]} | |
(into clojure.lang.PersistentQueue/EMPTY | |
(concat v (pq->vec pq)))) | |
(defn prequeue | |
"Adds interceptors to the front of context's execution queue. Creates | |
the queue if necessary. Returns updated context." | |
[context interceptors] | |
{:pre (every? interceptor/interceptor? interceptors)} | |
(log/trace :prequeue (map name interceptors) :context context) | |
;; NB: use ::chain/queue to match the namespace of the context key, | |
;; but this would change to ::queue if/when this went upstream. | |
(let [chain-pq (get-in context [::chain/queue]) | |
combined (pq-prepend chain-pq interceptors)] | |
(assoc-in context [::chain/queue] combined))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment