Skip to content

Instantly share code, notes, and snippets.

@crimeminister
Created May 4, 2017 22:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save crimeminister/14d87055b893cb1c0c11dd3eb5f84458 to your computer and use it in GitHub Desktop.
Save crimeminister/14d87055b893cb1c0c11dd3eb5f84458 to your computer and use it in GitHub Desktop.
Pedestal "prequeue" utility method for prepending interceptors to the interceptor chain
;; 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