Interceptors

sunng87 edited this page Feb 21, 2012 · 5 revisions
Clone this wiki locally

Interceptors

On slacker server, you can configure interceptors to add custom, additional functions. Each interceptor receives a request map contains information about the function call. You can read / update / add data to this map and pass it to next interceptor (or server handler).

Predefined interceptor

Slacker ships some predefined interceptors which is common used.

  • slacker.interceptors.stats/function-call-stats is a statistic on how many times each function called via slacker server. The data is exposed via JMX, which you can view with tools like jconsole.
  • slacker.interceptors.exectime/exectime-stats summarize call time of most recent 50 calls of each function, and expose via JMX.
  • slacker.interceptors.slowwatchdog/slow-watch-dog logs slow function calls and arguments.
  • slacker.interceptors.logargs/logargs logs arguments that causes a server side exception.

Using interceptors

To add interceptors, using the option :interceptors when you start slacker server.

(start-slacker-server (the-ns 'slapi) 2104
  :interceptors logging-interceptor)

If you have multiple interceptors, you should combine them with macro slacker.interceptor/interceptors.

(start-slacker-server (the-ns 'slapi) 2104
  :interceptors (interceptors logging-interceptor another-interceptor))

Write your own

You are encouraged to write interceptors for your own needs. Slacker has two macros definterceptor and definterceptor+ for interceptor development.

A practical example of the usage:

(definterceptor logging-interceptor
  :before (fn [req] (println (str "calling " (:fname req))) req)
  :after (fn [req] (println (str "called " (:fname req))) req))

Currently, there are two stages :before and :after to intercept the request processing. You can define interceptor for both of them or either one.

definterceptor+ allows you to use arguments to configure interceptors when using it. A code example:

(definterceptor+ logging-interceptor2 [prefix]
  :before (fn [req] (println (str prefix "calling " (:fname req))) req)
  :after (fn [req] (println (str prefix "called " (:fname req))) req))

(start-slacker-server ....  :interceptors (interceptors (logging-interceptor2 "=>>")))

You may have more practical example instead :-)

Request data

Attributes of the request object available to interceptors are :

  • before
    • :content-type content type of the request
    • :fname function name of the call, as string
    • :func function of the call
    • :args a vector of arguements
    • :client client connection information
  • after
    • :result the data returned by the function call
    • :code result code. :success, :exception or :not-found

You are free to add your own properties to request by assoc new key-value pairs to it.