|
1 | 1 | (ns intemporal.store |
2 | 2 | (:require [clojure.tools.reader.edn :as edn] |
3 | | - [intemporal.store.internal :refer [validate-task validate-event]] |
| 3 | + [intemporal.store.internal :as si] |
4 | 4 | [promesa.core :as p] |
5 | 5 | [taoensso.telemere :as t] |
6 | 6 | #?(:clj [clojure.java.io :as io])) |
|
13 | 13 |
|
14 | 14 | (defprotocol TaskStore |
15 | 15 | (list-tasks [this] "Lists all tasks") |
| 16 | + (task<-panic [this task-id error] |
| 17 | + "Terminates the task via panic; events should not be stored") |
16 | 18 | (task<-event [this task-id event-descr] |
17 | 19 | "Transitions the task. The task should be dequeued beforehand. Returns the event. |
18 | 20 | `event-descr` is one of: |
|
122 | 124 | (when-let [w (find-task this id)] |
123 | 125 | (maybe-fail!) |
124 | 126 | (->> (apply assoc w kvs) |
125 | | - (validate-task) |
| 127 | + (si/validate-task) |
126 | 128 | (swap! tasks assoc id))))] |
127 | 129 |
|
128 | 130 | ;; deser the db |
|
156 | 158 | (apply concat (vals @history))) |
157 | 159 | (save-event [this task-id event] |
158 | 160 | (let [evt+id (assoc event :id (swap! counter inc))] |
159 | | - (validate-event evt+id) |
| 161 | + (si/validate-event evt+id) |
160 | 162 | (swap! history (fn [v] |
161 | 163 | (assoc v task-id (-> (or (get v task-id) []) |
162 | 164 | (conj evt+id))))) |
|
171 | 173 | (list-tasks [this] |
172 | 174 | (vals @tasks)) |
173 | 175 |
|
| 176 | + (task<-panic [this task-id error] |
| 177 | + (update-task this task-id :result error)) |
| 178 | + |
174 | 179 | (task<-event [this task-id {:keys [id ref root type sym args result error] :as event-descr}] |
175 | 180 | ;; some redundancy between :result in task and event |
176 | 181 | ;; note that we save the event first, because update-task can trigger some watchers |
|
221 | 226 | (await-task this id {:timeout-ms default-lease})) |
222 | 227 |
|
223 | 228 | (await-task [this id {:keys [timeout-ms] :as opts}] |
224 | | - ;; TODO handle internal errors? use a separate state? |
225 | 229 | (maybe-fail!) |
| 230 | + ;; TODO use owner |
226 | 231 | (let [task (find-task this id) |
227 | 232 | deferred (p/deferred) |
228 | | - completed? (fn [{:keys [state]}] |
229 | | - (or (= :success state) |
230 | | - (= :failure state))) |
231 | | - wrap-result (fn [{:keys [state result] :as task}] |
| 233 | + wrap-result (fn [{:keys [result] :as task}] |
232 | 234 | (cond |
233 | | - (= :success state) (p/resolved result) |
234 | | - (= :failure state) (p/rejected result) |
| 235 | + (si/success? task) (p/resolved result) |
| 236 | + (si/failure? task) (p/rejected result) |
235 | 237 | :else (p/rejected (ex-info "Unknown state" {:task task}))))] |
236 | 238 |
|
237 | | - (if (completed? task) |
| 239 | + (if (si/terminal? task) |
238 | 240 | (wrap-result task) |
239 | 241 | ;;else |
240 | 242 | (do |
241 | | - (watch-task this id (fn [{:keys [state] :as task}] |
242 | | - (when (#{:success :failure} state) |
| 243 | + (watch-task this id (fn [task] |
| 244 | + (when (si/terminal? task) |
243 | 245 | (p/resolve! deferred task)))) |
244 | 246 | ;; wait for resolution |
245 | 247 | ;; remember: js doesnt have blocking op so we need to chain |
|
267 | 269 | (enqueue-task [this task] |
268 | 270 | ;; TODO use owner |
269 | 271 | (maybe-fail!) |
270 | | - (validate-task task) |
| 272 | + (si/validate-task task) |
271 | 273 | (swap! tasks assoc |
272 | 274 | (:id task) (assoc task :order (swap! tcounter inc))) |
273 | 275 | #?(:cljs (register this (:sym task) (:fvar task))) |
|
0 commit comments