This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-01-02
Channels
- # babashka (117)
- # babashka-sci-dev (6)
- # beginners (34)
- # biff (2)
- # calva (7)
- # clj-kondo (27)
- # clojure (6)
- # clojure-dev (8)
- # clojure-europe (41)
- # clojure-israel (1)
- # clojure-nl (1)
- # clojure-norway (2)
- # clojure-uk (1)
- # clojurescript (22)
- # cursive (3)
- # datascript (12)
- # dev-tooling (4)
- # emacs (13)
- # hyperfiddle (60)
- # introduce-yourself (8)
- # joyride (9)
- # lsp (46)
- # malli (3)
- # mranderson (75)
- # off-topic (40)
- # pathom (9)
- # pedestal (4)
- # reagent (11)
- # reitit (18)
- # releases (2)
- # shadow-cljs (81)
- # squint (18)
Having a race condition in photon between client/server state and can’t seem to figure out how to use Unglitch properly
The first glitch, what is the symptom you seeing? The picklist resultset changes and therefore the record for chosen index shifts?
ah, the on-pick runs only once (too late), not twice?
recently-searched-ents
is an atom on the server?
but it seems that because (reset! !input "")
runs, input
updates, suggestions
are recomputed for input
being ""
and then those suggestions
run in the p/server
expression
i understand
I tried binding a nil return value of the p/server block into the client to sequentialize execution but it did not help
What happens if you do this:
try moving it inside the p/server
one line down
Is there a way I can run this?
(when show-suggestions?
(suggestions-fn. (p/Unglitch. input)))
Another option is
(when (p/server
(let [picked (get suggestions idx)]
(if picked
(on-pick. picked)
#_(on-create. input))
true))
(reset! !input ""))
but this will lag your UIpicked (get (p/Unglitch. suggestions) idx)
as well, the goal is to slow down the suggestions query as it is updating too fast
i'll try again later today, i need to eat lunch
i dont understand
with this is runs twice https://clojurians.slack.com/archives/C7Q9GSHFV/p1672687807671769?thread_ts=1672681969.404549&cid=C7Q9GSHFV
show me your code with logs
(do
(.preventDefault e)
(println :running-client)
(when (p/server
(println :running-server (count suggestions))
(let [picked (get suggestions idx)]
(if picked
(on-pick. picked)
#_(on-create. input))
true))
;; FIXME can't run this due to glitch bug
;; p/Unglitch. is not working
(reset! !input ""))
)
;; =>
;; :running-server 2
;; :running-server 20
if this doesn’t help I’ll try to modify the Typeahead view this is based on to fail in the same way
yeah that's where i will start when i try again
(do
(.preventDefault e)
(when (p/Unglitch. input)
(p/server
(let [picked (get suggestions idx)]
(if picked
(on-pick. picked)
#_(on-create. input))
true)))
(reset! !input ""))
I think this isn't related to the distribution glitch. on-pick
and on-create
might not finish running because you reset!
and cause new reactions. What
you're looking for is to run the reset!
after the photon function runs.
If a photon function transfers it will throw a Pending exception first. We can
use a when
or case
to wait for exceptions to resolve before running
subsequent code. Try this version:
(case (if picked (on-pick. picked) (on-create. input))
(p/client (reset! !input "")))
I find this unreadable since it doesn't capture the intent so I would use a
macro like:
(defmacro sequential [& body] (when (seq body) (reduce (fn [ac nx] `(case ~nx ~ac)) (reverse body))))
to write:
(sequential
(if picked (on-pick. picked) (on-create. input))
(p/client (reset! !input "")))
It's the same code but more intentive and the macro allows chaining further without nesting, e.g.
(case (foo)
(case (bar)
(case (baz)
(quux))))
;; vs.
(sequential (foo) (bar) (baz) (quux))
Please consider this a hack more than a solution. Our goal is to find patterns
where code like this is not necessary.
If this still doesn't resolve your issue it'd be great to have a snippet we can run locally 😉the problem with "sequential" is it delays the UI from updating locally until after the server effect finishes
the problem iiuc is when we press enter, we race the clearing of the input (and subsequent refresh of the options due to the input clearing) - we race that with the change handler which is intended to be a discrete side effect that should happen only once. The goal is to make the keyboard-event DAG unmount before the change handler runs again, and unglitch is a way to delay the query reactions in response to clearing the input until after that keyboard-event DAG unmounts.
Perhaps calling it the d-glitch is not accurate but i think unglitch solves it for now
obviously i am vulnerable to having missed something because my suggestions didn't work (including the suggestion to sequence the effect and accept a lagged UI)
we will land a real solution to this along with photon-dom2 and photon-ui3 and the photon runtime fix to the d-glitch, which will all likely come together in about a month
thanks! I just tried this locally and the temporary fix I posted solves your issue
this makes sure !input
is reset only after the callback has run, solving the race.
We'll be working on new ui components, including new typeaheads, in the coming weeks
thanks @U09FL65DK that fixed it :)
turns out that https://clojurians.slack.com/archives/C7Q9GSHFV/p1672823518093869?thread_ts=1672681969.404549&cid=C7Q9GSHFV actually still runs twice, the reason it works that on the second run picked
is nil
and therefore on-pick
does not re-run