Skip to content

Commit 0f6e80f

Browse files
Bailey Kocinghaskins
authored andcommitted
add new allSettled handler
Signed-off-by: Bailey Kocin <bkocin@crossbeam.com>
1 parent 06c2394 commit 0f6e80f

File tree

5 files changed

+63
-7
lines changed

5 files changed

+63
-7
lines changed

src/temporal/client/schedule.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
```"
5151
[^ScheduleClient client schedule-id options]
5252
(let [schedule (s/schedule-> options)
53-
schedule-options (s/schedule-options-> options)]
53+
schedule-options (s/schedule-options-> (:schedule options))]
5454
(log/tracef "create schedule:" schedule-id)
5555
(.createSchedule client schedule-id schedule schedule-options)))
5656

src/temporal/internal/promise.clj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
;; Copyright © Manetu, Inc. All rights reserved
22

33
(ns ^:no-doc temporal.internal.promise
4-
(:require [taoensso.timbre :as log]
5-
[promesa.protocols :as pt]
4+
(:require [promesa.protocols :as pt]
65
[temporal.internal.utils :refer [->Func] :as u])
76
(:import [clojure.lang IDeref IBlockingDeref]
87
[io.temporal.workflow Promise]

src/temporal/internal/schedule.clj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
(ns ^:no-doc temporal.internal.schedule
2-
(:require [clojure.walk :refer [stringify-keys]]
3-
[temporal.internal.utils :as u]
2+
(:require [temporal.internal.utils :as u]
43
[temporal.internal.workflow :as w])
54
(:import [io.temporal.api.enums.v1 ScheduleOverlapPolicy]
65
[io.temporal.client.schedules

src/temporal/promise.clj

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,31 @@ promises returned from [[temporal.activity/invoke]] from within workflow context
3030
(p/then (fn [_]
3131
(mapv deref coll)))))
3232

33+
(defn allSettled
34+
"Returns Promise that becomes completed when all arguments are completed, even in the face of errors.
35+
36+
*N.B. You must handle the exceptions in the returned promises when done*
37+
38+
Similar to [promesa/all](https://funcool.github.io/promesa/latest/promesa.core.html#var-all) but designed to work with
39+
promises returned from [[temporal.activity/invoke]] from within workflow context.
40+
41+
For more Java SDK samples example look here:
42+
https://github.com/temporalio/samples-java/tree/main/core/src/main/java/io/temporal/samples/batch
43+
44+
```clojure
45+
(-> (allSettled [(a/invoke activity-a ..) (a/invoke activity-b ..)])
46+
(promesa.core/then (fn [[a-result b-result]] ...)))
47+
```
48+
"
49+
[coll]
50+
(letfn [(wait! [^Promise p] (try (.get p) (catch Exception _)))]
51+
(-> (into-array Promise (mapv wait! (->array coll)))
52+
(Promise/allOf)
53+
(pt/->PromiseAdapter)
54+
;; The promises are all completed at this point,
55+
;; this is just to use the promesa library
56+
(p/then (fn [_] (mapv deref coll))))))
57+
3358
(defn race
3459
"Returns Promise that becomes completed when any of the arguments are completed.
3560
@@ -54,4 +79,4 @@ promises returned from [[temporal.activity/invoke]] from within workflow context
5479
(defn rejected
5580
"Returns a new, rejected promise"
5681
[^Exception e]
57-
(Workflow/newFailedPromise e))
82+
(Workflow/newFailedPromise e))

test/temporal/test/concurrency.clj

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,37 @@
3232
(testing "Verifies that we can launch activities in parallel"
3333
(let [workflow (t/create-workflow concurrency-workflow)]
3434
(c/start workflow {})
35-
(is (-> workflow c/get-result deref count (= 10))))))
35+
(is (-> workflow c/get-result deref count (= 10))))))
36+
37+
(defactivity all-settled-activity
38+
[ctx args] args)
39+
40+
(defworkflow all-settled-workflow
41+
[args]
42+
@(-> (pt/all (map #(a/invoke all-settled-activity %) (range 10)))
43+
(p/then (fn [r] r))
44+
(p/catch (fn [e] (:args (ex-data e))))))
45+
46+
(defactivity error-prone-activity
47+
[ctx args]
48+
(when (= args 5)
49+
(throw (ex-info "error on 5" {:args args})))
50+
args)
51+
52+
(defworkflow error-prone-workflow
53+
[args]
54+
@(-> (pt/all (map #(a/invoke error-prone-activity %) (range 10)))
55+
(p/then (fn [r] r))
56+
(p/catch (fn [e] (:args (ex-data e))))))
57+
58+
(deftest test-all-settled
59+
(testing "Testing that allSettled waits for all the activities to complete
60+
just like `p/all` does in spite of errors"
61+
(let [workflow (t/create-workflow all-settled-workflow)]
62+
(c/start workflow {})
63+
(is (-> workflow c/get-result deref count (= 10)))))
64+
(testing "Testing that allSettled waits for all the activities to complete
65+
despite error and can return the errors"
66+
(let [workflow (t/create-workflow error-prone-workflow)]
67+
(c/start workflow {})
68+
(is (-> workflow c/get-result deref (= 5))))))

0 commit comments

Comments
 (0)