0.1.2 docs





    Dec 17, 2013



    Index of all namespaces

    The README below is fetched from the published project artifact. Some relative links may be broken.


    Provides a Clojure library to layer functions into a single process workflow. Like the Clojure multimethod functionality, process allows for the ability to execute branches of logic based on the context of function call(arguments, etc).

    Similaritities multimethod process
    Define a callable function clojure.core/defmulti pliant.process/defprocess
    Define branches of logic to execute clojure.core/defmethod pliant.process/deflayer

    But process differs in how the dispatching is performed. Where multimethod defines a single dispatch function and matches the value it returns to a single method to execute, process allows for each layer that is added to it, starting with the first layer in order, to determine if it will execute or not, as well as whether it will allow the next layer to be executed.

    Differences multimethod process
    Dispatching Single dispatch function that is matched to a single method to execute Each layer determines if it is executed.
    Workflow of execution None. Only one method is executed. Can execute one or many layers on a single call, as well as skipping over layers and performing callbacks.
    Default logic execution Available when method is added with :default dispatch value Inherent in the defining of defmethod
    Ordering vs Prefer Prefers one method over another with same dispatch value with prefer-method Can set order of execution of layers with before


    Creating a process is just like creating a function, except instead of using defn you use pliant.process/defprocess .

    (use 'pliant.process)
    (defprocess myprocess
      "This is my process doc"
      [arg1 arg2]
      (println "Running default logic with args:" arg1 arg2))

    The process function myprocess can be called just like a normal function.

    user=> (myprocess 1 2)
    Running default logic with args: 1 2

    Adding a layer to the process is done using pliant.process/deflayer.

    (deflayer myprocess mylayer1 
      [arg1 arg2] 
      (if (= arg2 4) 
        (println "Running layer1 logic with args:" arg1 arg2) 
    user=> (myprocess 1 2)
    Running default logic with args: 1 2
    user=> (myprocess 1 4)
    Running layer1 logic with args: 1 4


    Differences emerge from multimethod when execution is based off of different criteria:

    (deflayer myprocess mylayer2 
      [arg1 arg2] 
      (if (:doit arg1) 
        (println "Running layer2 logic with args:" arg1 arg2) 
    (deflayer myprocess mylayer3
      [arg1 arg2] 
      (if (roles/is-manager (session/user))
        (println "Running layer3 logic with args:" arg1 arg2) 

    Ordering Execution

    By default layers are executed in the order that they are read into Clojure. To change the order you can currently use the pliant.process/before function.

    user=> (before mylayer3 mylayer2)

    Flow Control

    Controlling the flow of a process is performed by calling one of the flow control functions at the end of your logic, which returns a value to the processes internal controller. If a layer returns any value, including nil, that is not generated from one of the flow control functions the execution of the process is considered complete and that value is returned. The available flow control functions are:

    Control Flow Function Instruction
    *pliant.process/continue* Continue to and attempt to execute the next layer on the process.
    *pliant.process/skip* Continue to and attempt to execute the next layer on the process. Skip a layer if it matches any of the layer functions that have been provided to the skip function.
    *pliant.process/callback* Continue to and attempt to execute the next layer on the process. When finished executing layers execute the function provided with the value returned from the last layer.
    *pliant.process/skipback* Continue to and attempt to execute the next layer on the process. Combines the ability to skip layers and perform a callback.

    Continue Example

    (deflayer myprocess mycontinue 
      [arg1 arg2] 
      (if (= arg1 arg2) 

    Skip Example

    (deflayer myprocess myskip 
      [arg1 arg2] 
      (if (= arg1 arg2) 
        (skip mycontinue) 

    Callback Example

    (deflayer myprocess mycallback 
      [arg1 arg2] 
      (if (= arg1 arg2) 
        (callback (fn [val] (if val "Yes" "Nope"))) 

    Skipback Example

    (deflayer myprocess myskipback
      [arg1 arg2] 
      (if (= arg1 arg2) 
        (skipback (fn [val] (if val "Yes" "Nope")) mycontinue) 

    Process As Method

    In order to combine the patterns that multimethod and process provide, the pliant.process/as-method function enables integration between the two.

    (defmulti handle-http uri->process) ;; uri->keyword psuedo fn to change a http request uri to a keyword
    (defprocess root [request] (redirect "/login"))
    (defprocess login [request] (render-login))
    (as-method root handle-http :get)
    (as-method login handle-http :get-login)
    (deflayer login shib-login [request] (if (auth/use-shib? request) (redirect-to-shib request) (continue))