Fork me on GitHub
#hyperfiddle
<
2023-03-03
>
J16:03:15

Hi guys! Is this a valid mount (`on-mount`) operation: (e/server (e/offload #(do something)) ? Here (https://gist.github.com/jeans11/c758a40842b30b11c1e324c99ab39620) when a client goes into an Item the List of the other client is updated indefinitely. Maybe the mount operation is not in the right place? I’m missing something :thinking_face:

2
Dustin Getz16:03:04

does it happen when someone clicks?

Dustin Getz16:03:07

i need more info

Dustin Getz16:03:49

also are you running latest? (v2-alpha-123)

Dustin Getz16:03:23

(e/server (e/offload #(update-item-visits item-eid (:user state))) nil) this is transacting during render, is that what you intend?

Dustin Getz16:03:42

It might be infinite looping (transacting your db in a tight loop)

Dustin Getz16:03:42

no, i dont see how it could be looping actually

J16:03:18

I’m not yet on the latest version. Sorry for the missing information. Yes this is the line. When someone click on an item the list of an other client start an infinite loop.

Dustin Getz16:03:41

Please first try v2-123, and then if that doesn't work can you minimize it down to something I can run? instead of transact try swapping an atom

👍 2
J16:03:40

I tested with the last release and with a simple atom. It works perfectly. But with a db like datascript or datalevin this happen: (PS: without e/offload on each server call, there is no problem)

👀 2
Dustin Getz14:03:03

Ok, this is a known issue that we know how to fix, we hope to start tomorrow

Dustin Getz14:03:23

Can you just remove the e/offload call for now?

Dustin Getz14:03:48

Also @UHZPYLPU1 can i see the exact source code for that video

J14:03:14

Hi @U09K620SG, thanks for your answer. The source code of that video is available here https://gist.github.com/jeans11/c758a40842b30b11c1e324c99ab39620

J09:03:18

Related to the e/offload issue, I notice an unexpected behaviour of e/on-unmount with the presence of an e/offload in a component (maybe because I try with no catch Pending ). It seems that e/on-unmount is directly call when the component is rendering.

xificurC09:03:30

:item/visits [n] looks fishy. It should be a single number, not sure what this will do, probably since you marked it card-many and n is always nil it'll have many [nil] s in the db. Does datalevin support transaction functions? You need an atomic increment, so either a CAS operator, a transaction function, or use https://cljdoc.org/d/datalevin/datalevin/0.8.5/api/datalevin.core#with-transaction

xificurC09:03:30

e/on-unmount will only run when your component is unmounting. Can you show your code?

J10:03:07

> :item/visits [n] looks fishy. It should be a single number, not sure what this will do, probably since you marked it card-many and n is always nil it’ll have many [nil] s in the db. Does datalevin support transaction functions? You need an atomic increment, so either a CAS operator, a transaction function, or use https://cljdoc.org/d/datalevin/datalevin/0.8.5/api/datalevin.core#with-transaction Hi @U09FL65DK thanks for you message. Sorry the item/visits is not explicit. It store the id of the current user. When a user comes into an Item his id is added into the item/visits array.

J10:03:04

> e/on-unmount will only run when your component is unmounting. Can you show your code? I made a revision here https://gist.github.com/jeans11/c758a40842b30b11c1e324c99ab39620 to add the e/on-unmount. (e/on-unmount #(do (prn "FOO") (retract-item-visits item-eid (:user state)))) In fact, the (prn "FOO") is print when the component is rendering (cf. screencast).

xificurC10:03:52

re item/visits: I see. In that case I think the vector wrapping isn't needed, you should be able to just transact n directly

xificurC10:03:48

re on-unmount: can you try putting it on the client with just the (prn "FOO")? I.e. move it out of the server block

J10:03:52

> you should be able to just transact n directly You right! > can you try putting it on the client with just the (prn "FOO")? I.e. move it out of the server block I put (e/on-unmount #(prn "FOO"))) directly in the client and it works as expected.

xificurC10:03:58

I think what's happening is • your update-item-visits call runs on render and it transacts • this triggers a new db value • now item on line 75 is re-run, throwing Pending first • this makes item-eid Pending too • item-eid is inside the on-unmount call, so it also throws, therefore unmounts

xificurC10:03:19

you could try a refactor where Item already takes the item-eid as an argument. Resolve it on the server, without any offloads so it'll never be pending

xificurC10:03:33

something like (Item. !state state (d/q '[:find ?e . :in $ ?id :where [?e :item/id ?id]] db (:id state)))

xificurC10:03:25

we'll get back to you with more idioms/best practices to make this easier

J10:03:20

@U09FL65DK thanks for your explanation (very helpfull). It will be great, indeed, to have a guide of this.

J16:03:52

Hi @U09K620SG yes, it’s ok!

denik20:03:07

started using photon for better debugging, e.g. watching client or server atoms in the dom:

denik20:03:13

(e/defn AtomPre [label a]
  (let [v (e/watch a)]
    (when v
      (e/client
        (dom/div
          (dom/props {:style {:display :flex
                              :gap     :5px}})
          (dom/div (dom/text label))
          (dom/pre (dom/props {:style {:margin 0}}) (dom/text (pr-str v))))))))

2
2
👀 4