Skip to content

Commit 39c30cb

Browse files
committedJul 31, 2024·
Race client requests and remove connection on timeout
1 parent fb129cf commit 39c30cb

File tree

2 files changed

+87
-34
lines changed

2 files changed

+87
-34
lines changed
 

‎src/portal/runtime/clr/client.clj

+42-17
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,51 @@
2727
(remove-watch rt/connections watch-key)
2828
result)))
2929

30+
(defn- request! [session-id message]
31+
(if-let [send! (get-connection session-id)]
32+
(let [id (rt/next-id)
33+
response (promise)
34+
message (assoc message :portal.rpc/id id)]
35+
(swap! rt/pending-requests assoc id response)
36+
(send! message)
37+
(let [response (deref response timeout ::timeout)]
38+
(swap! rt/pending-requests dissoc id)
39+
(if-not (= response ::timeout)
40+
response
41+
(throw (ex-info "Portal request timeout"
42+
{:session-id session-id :message message})))))
43+
(throw (ex-info "No such portal session"
44+
{:session-id session-id :message message}))))
45+
46+
(defn- broadcast! [message]
47+
(when-let [sessions (keys @rt/connections)]
48+
(let [response (promise)]
49+
(doseq [session-id sessions]
50+
(future
51+
(try
52+
(deliver response (request! session-id message))
53+
(catch Exception ex
54+
(when (-> ex ex-data ::timeout)
55+
(swap! rt/connections dissoc session-id))
56+
(deliver response ex)))))
57+
(let [response (deref response timeout ::timeout)]
58+
(cond
59+
(instance? Exception response)
60+
(throw response)
61+
(not= response ::timeout)
62+
response
63+
:else
64+
(throw (ex-info
65+
"Portal request timeout"
66+
{::timeout true
67+
:session-id :all
68+
:message message})))))))
69+
3070
(defn request
3171
([message]
32-
(last
33-
(for [session-id (keys @rt/connections)]
34-
(request session-id message))))
72+
(broadcast! message))
3573
([session-id message]
36-
(if-let [send! (get-connection session-id)]
37-
(let [id (rt/next-id)
38-
response (promise)
39-
message (assoc message :portal.rpc/id id)]
40-
(swap! rt/pending-requests assoc id response)
41-
(send! message)
42-
(let [response (deref response timeout ::timeout)]
43-
(swap! rt/pending-requests dissoc id)
44-
(if-not (= response ::timeout)
45-
response
46-
(throw (ex-info "Portal request timeout"
47-
{:session-id session-id :message message})))))
48-
(throw (ex-info "No such portal session"
49-
{:session-id session-id :message message})))))
74+
(request! session-id message)))
5075

5176
(defn- push-state [session-id new-value]
5277
(request session-id {:op :portal.rpc/push-state :state new-value})

‎src/portal/runtime/jvm/client.clj

+45-17
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,54 @@
2727
(remove-watch rt/connections watch-key)
2828
result)))
2929

30+
(defn- request! [session-id message]
31+
(if-let [send! (get-connection session-id)]
32+
(let [id (rt/next-id)
33+
response (promise)
34+
message (assoc message :portal.rpc/id id)]
35+
(swap! rt/pending-requests assoc id response)
36+
(send! message)
37+
(let [response (deref response timeout ::timeout)]
38+
(swap! rt/pending-requests dissoc id)
39+
(if-not (= response ::timeout)
40+
response
41+
(throw (ex-info
42+
"Portal request timeout"
43+
{::timeout true
44+
:session-id session-id
45+
:message message})))))
46+
(throw (ex-info "No such portal session"
47+
{:session-id session-id :message message}))))
48+
49+
(defn- broadcast! [message]
50+
(when-let [sessions (keys @rt/connections)]
51+
(let [response (promise)]
52+
(doseq [session-id sessions]
53+
(future
54+
(try
55+
(deliver response (request! session-id message))
56+
(catch Exception ex
57+
(when (-> ex ex-data ::timeout)
58+
(swap! rt/connections dissoc session-id))
59+
(deliver response ex)))))
60+
(let [response (deref response timeout ::timeout)]
61+
(cond
62+
(instance? Throwable response)
63+
(throw response)
64+
(not= response ::timeout)
65+
response
66+
:else
67+
(throw (ex-info
68+
"Portal request timeout"
69+
{::timeout true
70+
:session-id :all
71+
:message message})))))))
72+
3073
(defn request
3174
([message]
32-
(last
33-
(for [session-id (keys @rt/connections)]
34-
(request session-id message))))
75+
(broadcast! message))
3576
([session-id message]
36-
(if-let [send! (get-connection session-id)]
37-
(let [id (rt/next-id)
38-
response (promise)
39-
message (assoc message :portal.rpc/id id)]
40-
(swap! rt/pending-requests assoc id response)
41-
(send! message)
42-
(let [response (deref response timeout ::timeout)]
43-
(swap! rt/pending-requests dissoc id)
44-
(if-not (= response ::timeout)
45-
response
46-
(throw (ex-info "Portal request timeout"
47-
{:session-id session-id :message message})))))
48-
(throw (ex-info "No such portal session"
49-
{:session-id session-id :message message})))))
77+
(request! session-id message)))
5078

5179
(defn- push-state [session-id new-value]
5280
(request session-id {:op :portal.rpc/push-state :state new-value})

0 commit comments

Comments
 (0)
Please sign in to comment.