Fork me on GitHub
#hyperfiddle
<
2023-09-03
>
Dustin Getz17:09:07

Anyone who is overriding *ws-server-url* I am making changes to how this works (to auto-wire the client/server version check in the connect string), please reply here if you have customized this and paste me a snippet showing me how you did it

grounded_sage18:09:14

(set! client/*ws-server-url* "") I am script tagging on a different domain and client/*ws-server-url* appeared to be pulling the current host domain. Was unclear how this could be done another way.

grounded_sage21:09:26

I had also changed the string name as I didn't want people knowing what we were using under the hood. But if they are already smart enough to go into devtools they could figure it out.

Garrett Hopper22:09:11

I have it overridden for storybook, but it's only necessary in Dev of course, so the client version is blank.

grounded_sage18:09:41

Has anyone got a code snippet of debouncing user text input with missionary? I still haven't grokked it and see references to m/observe and m/relieve when I search debouncing in the chat here.

👍 1
Dustin Getz18:09:29

debounce is a UI anti-pattern due to introducing latency artificially (never slow down the user from doing what they want)

Dustin Getz18:09:34

please state the problem you're trying to solve?

grounded_sage18:09:27

I am doing a text search on the database. So was going to debounce the calls by around 150ms and check if there is new results. Two reasons: 1. Not querying the database on every single keypress 2. Currently the UI flickers on each added or removed character

Dustin Getz18:09:34

the UI flickering indicates something else bad is happening, that should be fixed separately

👍 2
Dustin Getz18:09:56

to throttle the database i recommend putting the throttling code around the database, not around the user input

Dustin Getz18:09:05

per the other discussions you found via search, you want to allow the first request through and cancel it if new requests arrive that supersede the old request

👍 2
Dustin Getz18:09:17

if the database supports cancellation (respects ThreadInterruptException which missionary will raise when the query call has been superseded by a newer query call), there's nothing you need to do, and you definitely do not need to add delays

Dustin Getz18:09:36

the old superseded query will be interrupted/discarded and the new query takes precedence

Dustin Getz19:09:09

if the database doesn't support cancellation (does not respect ThreadInterruptException) then what will happen is the query will need to finish before serving the next query

Dustin Getz19:09:20

in this case i dont think there is anything for you to do either

Dustin Getz19:09:36

it will just be slower because the database is failing to respect the cancellation signal and therefore is making the clients wait for delivery of a query result that is irrelevant and will be ignored/discarded

👍 2
grounded_sage19:09:33

This is incredibly valuable info.

☝️ 2
grounded_sage19:09:13

I will investigate further into my UI flickering. I thought it might have been my error but then thought it could be something to do with the database interaction.

Dustin Getz19:09:14

in this slow case, due to continous time work skipping, if you button mash the text input, missionary (electric) will skip all the intermediate inputs and jump straight to the latest value of the input

Dustin Getz19:09:12

Per my current understanding of UI programming in Electric, the only time you'd ever want to artifically throttle something is a side effecting call like d/transact

Dustin Getz19:09:59

if you smash Datomic d/transact rapidly, it gets confused and crashes or hangs or something due to concurrency bugs in Datomic, I forget the details

Dustin Getz19:09:24

that is a case where adding artifical latency is sensible – to work around broken dependencies

Dustin Getz19:09:32

in Datomic's defense, it was not designed for d/transact to be rapidly invoked, so it is abusive for a reactive app to use it like that. (Nonetheless, databases should not be crashing)

grounded_sage19:09:20

I will definitely see about this being added to Datahike. I'm glad I have an opportunity to really use all these tools and see where they can work better together.

Dustin Getz19:09:23

So in the case of transacting rapidly into a database, and assuming that it's not an abuse of the database, the stream of effects can be throttled with missionary to not overwhelm it

grounded_sage19:09:44

Okay this UI flicker I am uncertain on. All of this is in a let binding.

!search-text (atom nil)
        search-text (e/watch !search-text)
        conversations (if-not search-text
                        (e/server
                         (sort-by first > (d/q '[:find ?created ?e ?conv-id ?topic
                                                 :where
                                                 [?e :conversation/id ?conv-id]
                                                 [?e :conversation/topic ?topic]
                                                 [?e :conversation/created ?created]
                                                 [?e :conversation/folder :default]]
                                               db)))
                        
                        
                        ;; This server call causes a UI flicker
                        (e/server 
                         (let [convo-eids (d/q '[:find [?c ...]
                                                 :in $ search-txt ?includes-fn
                                                 :where
                                                 [?m :message/text ?msg-text]
                                                 [?c :conversation/messages ?m]
                                                 [?c :conversation/topic ?topic]
                                                 (or
                                                  [(?includes-fn ?msg-text search-txt)]
                                                  [(?includes-fn ?topic search-txt)])]
                                               db search-text lowercase-includes?)]
                           (sort-by first > (d/q '[:find ?created ?e ?conv-id ?topic
                                                   :in $ [?e ...]
                                                   :where
                                                   [?e :conversation/id ?conv-id]
                                                   [?e :conversation/topic ?topic]
                                                   [?e :conversation/created ?created]
                                                   [?e :conversation/folder :default]]
                                                 db convo-eids)))))
Input
(dom/input (dom/props {:class "w-full flex-1 rounded-md border border-neutral-600 bg-[#202123] px-4 py-3 pr-10 text-[14px] leading-3 text-white"
                                             :placeholder "Search..."
                                             :value search-text})
                                 (dom/on "keyup" (e/fn [e]
                                                   (if-some [v (empty->nil (.. e -target -value))]
                                                     (reset! !search-text v)
                                                     (reset! !search-text nil)))))

grounded_sage20:09:58

The one with a single query does not flicker. The one with the two queries does flicker. The results are sorted by date before being returned from the server. As I type the flicker occurs when nothing changes in the results.

Dustin Getz20:09:01

try e/offload around any heavy lifting (that would include the sort)

grounded_sage20:09:15

hmm I still seem to get a flicker. I also tried it with m/cpu playing around with variations on the code to see if there is more info I can provide.

Dustin Getz20:09:53

We will probably have to take a look, flicker isn't something I have seen a lot