001 (ns cmp.resp
002 ^{:author "wactbprot"
003 :doc "Catches responses and dispatchs."}
004 (:require [cheshire.core :as che]
005 [cmp.config :as config]
006 [cmp.exchange :as exch]
007 [cmp.doc :as doc]
008 [cmp.lt-mem :as lt]
009 [cmp.st-mem :as st]
010 [cmp.st-utils :as stu]
011 [cmp.utils :as u]
012 [com.brunobonacci.mulog :as mu]))
013
014
015
016 (defn retry!
017 [state-key]
018 (let [retry-key (stu/key->retry-key state-key)
019 n (u/ensure-int (st/key->val retry-key))
020 n-max (config/max-retry (config/config))]
021 (if (>= n n-max)
022 (do
023 (mu/log ::retry! :error "reached max-retry" :key state-key)
024 (st/set-val! retry-key 0)
025 {:error "max retry"})
026 (do
027 (mu/log ::retry! :message (str "retry " n "/" n-max) :key state-key)
028 (st/set-val! retry-key (inc n))
029 {:ok "retry"}))))
030
031
032
033 (defn dispatch
034 "Dispatches responds from outer space. Expected responses are:
035
036 * Result ... data will be stored in long term memory
037 * ToExchange ... data goes to exchange interface
038 * ids ... renew the active documents
039 * error ... state will be set to error, processing stops
040
041 It's maybe a good idea to save the respons body to a key associated
042 to the state key (done).
043
044 TODO: detect missing values that should be measured again.
045 Solution: Missing or wrong values are detected at postscripts which
046 leads to `:Retry true`. "
047 [body task state-key]
048 (mu/log ::dispatch :message "try to write response" :key state-key )
049 (st/set-val! (stu/key->response-key state-key) body)
050 (if-let [err (:error body)]
051 (st/set-state! state-key :error err)
052 (let [retry (:Retry body)
053 to-exch (:ToExchange body)
054 results (:Result body)
055 ids (:ids body)
056 doc-path (:DocPath task)
057 mp-id (:MpName task)]
058 (if retry
059 (let [res-retry (retry! state-key)]
060 (cond
061 (:error res-retry) (st/set-state! state-key :error)
062 (:ok res-retry) (st/set-state! state-key :ready)))
063 (let [res-ids (doc/renew! mp-id ids)
064 res-exch (exch/to! mp-id to-exch)
065 res-doc (doc/store! mp-id results doc-path)]
066 (cond
067 (:error res-exch) (st/set-state! state-key :error "error at exchange")
068 (:error res-doc) (st/set-state! state-key :error "error at document")
069 (and
070 (:ok res-ids)
071 (:ok res-exch)
072 (:ok res-doc)) (st/set-state! state-key (if (exch/stop-if task) :executed :ready) "exch and doc ok")
073 :unexpected (st/set-state! state-key :error "unexpected response")))))))
074
075 ;;------------------------------
076 ;; check
077 ;;------------------------------
078 (defn check
079 "Checks a response from outer space. Lookes at the status, parses the
080 body and dispathes."
081 [res task state-key]
082 (if-let [status (:status res)]
083 (if-let [body (che/decode (:body res) true)]
084 (if (< status 400)
085 (dispatch body task state-key)
086 (mu/log ::check :error "request for failed" :key state-key ))
087 (mu/log ::check :error "body can not be parsed" :key state-key))
088 (mu/log ::check :error "no status in header" :key state-key)))