Advertisement
Guest User

Untitled

a guest
Jun 15th, 2019
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (ns web-sample.core
  2.   (:require [clojure.core.match :refer [match]]))
  3.  
  4. (defn register-user
  5.   []
  6.   (println "Register user")
  7.   (vector {:event-type :user-registered}
  8.           {:event-type :email-sended}))
  9.  
  10. (defn remove-user []
  11.   (println "Remove user")
  12.   (vector))
  13.  
  14. (defn run-command
  15.   [{:keys [command-type] :as command}]
  16.   (println "run-command " command)
  17.   (match command-type
  18.     :register-user (register-user)
  19.     :remove-user (remove-user)
  20.     :else (throw (Exception. (str "run-command !Wrong state " command)))))
  21.  
  22. (defn run-event
  23.   [{:keys [event-type] :as event}]
  24.   (match event-type
  25.     :user-registered (do
  26.                        (println "User registered event!")
  27.                        :fail)
  28.     :email-sended (do
  29.                     (println "Email sended event!")
  30.                     :ok)
  31.     :else :fail))
  32.  
  33. (defn register-user-cmd
  34.   [id name email]
  35.   {:command-type :register-user
  36.    :data {:id id
  37.           :name name
  38.           :email email}})
  39.  
  40. (defn remove-user-cmd
  41.   [id]
  42.   {:command-type :remove-user
  43.    :data {:id id}})
  44.  
  45. (defn add-compensation
  46.   [command compensation]
  47.   (assoc command :compensation compensation))
  48.  
  49. (defn make-register-user-command
  50.   [key data]
  51.   (match key
  52.     :register-user (let [{:keys [name email]} data
  53.                          id 1]
  54.                      (-> (register-user-cmd id name email)
  55.                          (add-compensation (remove-user-cmd id))))
  56.     :else nil))
  57.  
  58. (defn create-saga
  59.   [commands]
  60.   {:saga-type :in-forward
  61.    :commands commands
  62.    :complete (list)})
  63.  
  64. (defn saga-apply-command
  65.   [{:keys [saga-type commands complete] :as saga} {:keys [command-type] :as command}]
  66.   (match [saga-type command-type]
  67.     [:in-forward :proceed]
  68.     (let [[current & next] commands]
  69.       (if current
  70.         (let [events (run-command current)
  71.               event-statuses (map run-event events)]
  72.           (if (every? (partial = :ok) event-statuses)
  73.             (merge saga {:commands next
  74.                          :complete (cons current complete)})
  75.             (merge saga {:saga-type :in-backward
  76.                          :complete (empty complete)
  77.                          :commands (cons current complete)})))
  78.         (merge saga {:saga-type :done})))
  79.     [:in-backward :proceed]
  80.     (let [[current & next] commands]
  81.       (if current
  82.         (let [compensation-command (:compensation current)
  83.               events (run-command compensation-command)
  84.               event-statuses (map run-event events)]
  85.           (if (every? (partial = :ok) event-statuses)
  86.             (merge saga {:commands next
  87.                          :complete (cons current complete)})
  88.             (merge saga {:saga-type :fail})))
  89.         (merge saga {:saga-type :backward-done})))
  90.     :else (throw (Exception. (str "saga-apply-command !Wrong state " saga-type " " command-type)))))
  91.  
  92. (defn saga-next
  93.   [{:keys [saga-type]}]
  94.   (match saga-type
  95.     :in-forward {:command-type :proceed}
  96.     :in-backward {:command-type :proceed}
  97.     :else (throw (Exception. (str "saga-next !Wrong state " saga-type)))))
  98.  
  99. (defn request->command
  100.   [{:keys [body]}]
  101.   body)
  102.  
  103. (defn run-saga
  104.   [cmd1 & cmds]
  105.   (loop [{:keys [saga-type] :as saga} (create-saga (cons cmd1 cmds))]
  106.     (if (or (= :done saga-type)
  107.             (= :backward-done saga-type))
  108.       saga
  109.       (recur (saga-apply-command saga (saga-next saga))))))
  110.  
  111. (run-saga (make-register-user-command :register-user {:name "Vlad"
  112.                                                       :email "kuz@ff"} ))
  113.  
  114. ; (defn handle-command
  115. ;   [{:keys [type payload]}]
  116. ;   (case type
  117. ;     :register-user (run-saga (register-user-cmd))))
  118.  
  119. ; (defn request-handler [request]
  120. ;   (let [command (request->command request)]
  121. ;     (handle-command command)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement