hyperfiddle

braai engineer 2025-02-06T20:26:25.132799Z

How to catch a button click and execute server & client Electric code without an e/Token? My issue with e/Token token is that if I consume the token with (t), it seems to interrupt any in-flight server code (that isn't offloaded). Maybe I'm doing something wrong here:

(when-some [t (dom/button (dom/text "New Order")
                 (let [e (dom/On "click" identity nil)
                       [t err] (e/Token e)]
                   t))]
  (let [order-id (e/server (create-order! conn seller-id))] ; this returns an id.
    (r/Navigate! ['/ ['Orders order-id]])
    (t))) ;; consuming token here breaks r/Navigate! because it interrupts the when-some.
whereas it works if I take out the (t), but it feels like I'm leaking memory. (dom/on "click" (fn [] clojure-only) nil)) <= how to run e/server or e/client code on click?

Dustin Getz (Hyperfiddle) 2025-02-06T20:28:17.992399Z

yes you def are leaking memory if you don't dispose the token

Dustin Getz (Hyperfiddle) 2025-02-06T20:30:31.406159Z

the point of the token is to deal with failure, latency, retry, so the sequence of effects here should be • button click, construct token • query server, render busy state, wait for result • check server result for success or failure • if failure: don't navigate, use token to inject error back into the button so user can try again • if success: navigate

Dustin Getz (Hyperfiddle) 2025-02-06T20:30:56.087919Z

> it seems to interrupt any in-flight server code (that isn't offloaded) this i don't understand

Dustin Getz (Hyperfiddle) 2025-02-06T20:31:11.754589Z

Oh, (t) doesn't have any causal dependency on the server result order-id, that's why

Dustin Getz (Hyperfiddle) 2025-02-06T20:31:58.629239Z

(case order-id ::success (r/Navigate!), ::failure (t err))

braai engineer 2025-02-06T20:37:18.279389Z

Thanks, that works! Lotta people dumber than even me are gonna have a hard time with that. I sort of know how Electric works and spent an hour trying to figure out how I was using r/Navigate! wrong, until I accidentally took out the token consumption. We are not very wired for the implicit asynchronicity. btw. is there a way to keep track of unconsumed tokens? Guaranteed this is gonna be a big source of memory leaks.

👀 1
Dustin Getz (Hyperfiddle) 2025-02-06T20:37:36.010929Z

git gud, sorry

😄 3
braai engineer 2025-02-06T20:38:15.155989Z

I do miss just being able to pass an e/fn to a dom/on "click" event

Dustin Getz (Hyperfiddle) 2025-02-06T20:38:20.143849Z

we will probably add try/catch at some point which will help make this more natural looking

braai engineer 2025-02-06T20:38:41.027839Z

it's almost like Electric needs its own async IDE

Dustin Getz (Hyperfiddle) 2025-02-06T20:39:00.512599Z

you can implement a backwards compatible API that uses "callbacks", but we just think it has too many problems, we certainly don't want to encourage buggy patterns

braai engineer 2025-02-06T20:39:01.388179Z

"deez purple codes will run at same time" (hard, I know)

braai engineer 2025-02-06T20:39:47.351779Z

like rainbow parens for async-executing lines would be cool. I would have spotted that independent (t) instantly

Dustin Getz (Hyperfiddle) 2025-02-06T20:40:16.873449Z

well, it's all async, every expression is maximally concurrent

xificurC 2025-02-06T21:35:07.661119Z

do body is concurrently running every expression, I guess that's what got you?

xificurC 2025-02-06T21:42:23.803719Z

Re leaks - wrap your token fn in a timeout, something like

(e/defn TimeoutToken [nm ms t]
  (when t
    (case (e/Task (m/sleep ms))
      (do
        (prn 'leak nm)
        (t))))
  t)

xificurC 2025-02-06T21:45:06.441599Z

The token API is less glamorous for the easy case, we agree on that. But it brings immense benefits wrt composition

Dustin Getz (Hyperfiddle) 2025-02-07T00:13:23.077379Z

> is there a way to keep track of unconsumed tokens if you're correctly monitoring the token to render busy and failure states (as in the https://electric.hyperfiddle.net/tutorial/token_explainer), it will be very obvious that the token is undisposed because your button will be yellow

👍 1