Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (ns web-sample.core
- (:require [clojure.core.match :refer [match]]))
- (defn register-user
- []
- (println "Register user")
- (vector {:event-type :user-registered}
- {:event-type :email-sended}))
- (defn remove-user []
- (println "Remove user")
- (vector))
- (defn run-command
- [{:keys [command-type] :as command}]
- (println "run-command " command)
- (match command-type
- :register-user (register-user)
- :remove-user (remove-user)
- :else (throw (Exception. (str "run-command !Wrong state " command)))))
- (defn run-event
- [{:keys [event-type] :as event}]
- (match event-type
- :user-registered (do
- (println "User registered event!")
- :fail)
- :email-sended (do
- (println "Email sended event!")
- :ok)
- :else :fail))
- (defn register-user-cmd
- [id name email]
- {:command-type :register-user
- :data {:id id
- :name name
- :email email}})
- (defn remove-user-cmd
- [id]
- {:command-type :remove-user
- :data {:id id}})
- (defn add-compensation
- [command compensation]
- (assoc command :compensation compensation))
- (defn make-register-user-command
- [key data]
- (match key
- :register-user (let [{:keys [name email]} data
- id 1]
- (-> (register-user-cmd id name email)
- (add-compensation (remove-user-cmd id))))
- :else nil))
- (defn create-saga
- [commands]
- {:saga-type :in-forward
- :commands commands
- :complete (list)})
- (defn saga-apply-command
- [{:keys [saga-type commands complete] :as saga} {:keys [command-type] :as command}]
- (match [saga-type command-type]
- [:in-forward :proceed]
- (let [[current & next] commands]
- (if current
- (let [events (run-command current)
- event-statuses (map run-event events)]
- (if (every? (partial = :ok) event-statuses)
- (merge saga {:commands next
- :complete (cons current complete)})
- (merge saga {:saga-type :in-backward
- :complete (empty complete)
- :commands (cons current complete)})))
- (merge saga {:saga-type :done})))
- [:in-backward :proceed]
- (let [[current & next] commands]
- (if current
- (let [compensation-command (:compensation current)
- events (run-command compensation-command)
- event-statuses (map run-event events)]
- (if (every? (partial = :ok) event-statuses)
- (merge saga {:commands next
- :complete (cons current complete)})
- (merge saga {:saga-type :fail})))
- (merge saga {:saga-type :backward-done})))
- :else (throw (Exception. (str "saga-apply-command !Wrong state " saga-type " " command-type)))))
- (defn saga-next
- [{:keys [saga-type]}]
- (match saga-type
- :in-forward {:command-type :proceed}
- :in-backward {:command-type :proceed}
- :else (throw (Exception. (str "saga-next !Wrong state " saga-type)))))
- (defn request->command
- [{:keys [body]}]
- body)
- (defn run-saga
- [cmd1 & cmds]
- (loop [{:keys [saga-type] :as saga} (create-saga (cons cmd1 cmds))]
- (if (or (= :done saga-type)
- (= :backward-done saga-type))
- saga
- (recur (saga-apply-command saga (saga-next saga))))))
- (run-saga (make-register-user-command :register-user {:name "Vlad"
- :email "kuz@ff"} ))
- ; (defn handle-command
- ; [{:keys [type payload]}]
- ; (case type
- ; :register-user (run-saga (register-user-cmd))))
- ; (defn request-handler [request]
- ; (let [command (request->command request)]
- ; (handle-command command)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement