This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-12-22
Channels
- # adventofcode (12)
- # announcements (6)
- # aws (5)
- # babashka (57)
- # beginners (40)
- # calva (17)
- # clojure-europe (10)
- # clojure-nl (1)
- # clojure-norway (21)
- # clojure-uk (3)
- # clojuredesign-podcast (4)
- # cursive (3)
- # datomic (9)
- # etaoin (5)
- # fulcro (12)
- # hyperfiddle (42)
- # missionary (2)
- # off-topic (11)
- # reagent (6)
- # scittle (131)
- # squint (3)
- # tools-deps (4)
- # uncomplicate (1)
- # vscode (1)
I may have just missed it somewhere, but how can an electric user avoid the danger of remote code execution vulnerabilities? Especially with the dynamic nature of CLJ, it seems rather easy to get electric on the server to call any function with any args. Even if at compile time the list of acceptable fns is constrained to what the electric compiler identifies as existing fn calls, the api size is far larger than with a normal rest api.
server is fully determined and baked at compile time as of the new incremental compilation changes. not just the list of functions but also the access patterns
so, each unique context change from e/client
to e/server
is named and identified? cool, that sounds good.
yes the electric analyzer slices the system DAG in half, the cut edges are pub/sub (input/output) pairs with addresses used by the wire protocol
I am trying to get video working via dom/video, and I can't fast-forward. Can't distinguish if this is an Electric issue or something else.
(dom/video (props {:controls true :width "100%"})
(dom/element :source
(props {:src "southwell1.mp4"
:type "video/mp4"})))
if you suspect an electric interaction, you can always drop to vanilla js like (doto (js/document.createElement "video") (.appendChild dom/node) (.setProperty "src" "southwel1.mp4") ...)
(pseudocode)
It's not electric, it's jetty / ring. Fast forward requires the web server to support https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests. IIRC there's a ring middleware for that. S3 / CloudFront supports it ootb, also IIRC
I encountered the same thing, check this: https://github.com/formicagreen/electric-media-player
what is the best way to query for current time of the video as a missionary flow/electric value?
Some thoughts and questions… Apologies if none of this makes sense… Not an expert developer, just a curious person :) Apart from the whole frontend/backend transparency, one thing that makes Electric so nice is it lets you think of your app sort of like a spreadsheet. Ideally this would also be true for React et al, but in reality you end up with a lot of accidental complexity, lifecycle management etc. Less so with Electric. This made me think about “computed values” in a spreadsheet. This is sort of like a pure function operating on the db. My question is if Electric could “solve” cache invalidation for these kinds of values? Let’s say you have an “order” item that contains a bunch of product ids. And you want to show some compound information about the order and products. Normally you have to choose between: • Recomputing on every request • Caching the results, and having to come up with a strategy for invalidating the cache Could Electric potentially do this in an “ideal” way? I.e. you set a watcher on the db and updates “trickle down” to wherever they are needed? I’m not talking about frontend/backend sync here, just cache invalidation in general. Another example is a CMS / static site generator. Most of these have very simplistic models for how cache invalidation / partial regeneration are done. But on a large site, content may be interweaved in all kinds of ways, and predicting what pages are affected when a piece of content is updated becomes more complex. Taking this a step further, could you implement a kind of “event sourcing” system purely in Electric? E.g. “send email on new order”. I have been reading about Rama and from my limited understanding this is somewhat similar. But it seems difficult to learn and a bit overkill for the type of work I’m doing. I like that Electric looks like regular Clojure code.
Yes, most of this is already true in Electric v2, and with Differential Electric becomes fully true. With Differential Electric, instead of cache invalidation + recompute, you propagate diffs through the system and each "cache" (view) is incrementally maintained
the database watcher, if the database supports it, is the source of diffs (along with any other user events, atoms or sources of variability)
Re. Rama, Nathan is the right person to be building that, we have no interest in hyperscale backends, Electric is exclusively a UI technology, BYO data tier. Nonetheless, sure, hypothetically an Electric backend can "send email on new order", in the abstract this is the same as "add dom element for new order", however the devil is in the details. Rama offers a bunch of strong operational guarantees (like you'd get from a database) which Electric does not
Thanks for the explanation!
Hi, reviving this... thinking about the example again of a cms / static site generator. Would it be a viable to use electric (+ datomic or something) to generate a bunch of html files and minimally regenerate stuff when the database is updated? I.e. instead of "update dom when x y or z changes" it's "spit html file". Or would there be similar issues with operational guarantees? It seems like incremental maintenance + effects would be incredibly powerful in a bunch of contexts outside of ui. Like being able to model your entire app as a reactive system. Or are there established solutions for this that I'm not aware of? Again Rama seems very cool but I have no need for that kind of scaling. Another thing, do you think differential electric could potentially fix the perf issues I had with the drawing app?
yes, differential will fix some of the Painter app perf issues (the slowdown with eg. 1000 objects). the local first update issue will become possible to fix as well but will require a bit more work
yes, i think using electric to render and maintain static html files on disk should work in principle - you may hit edge cases though that need smoothing out
thanks again for taking the time to answer! really cool following this stuff
is there a way to ensure an that a e/defn flow invoked from within a dom handler completes? It currently appears that something refreshing in the UI cancels the flow which in turn cancels necessary DB transactions
ah, the rule here is: the e/fn is unmounted when the first non-Pending value is seen by the client
one of your snippets showed basically smashing d/transact as fast as the user types iirc – not sure if i read it properly – this is probably a bad fit for dom/on
(which we want to replace anyway due to all these surprising semantics)
the dom/on!
pattern bypasses all the surprising machinery, we like this primitive better
I may be mistaken, reading the src I see that dom/on
uses the strategy for each subsequent event to supersede the previous event, canceling and discarding the prior result, so that should be fine for smashing d/transact
upon re-reading this, i'm not sure that the behavior @U050CJFRU reports ("something refreshing in the UI cancels the flow") matches the intended behavior of dom/on, I think there still may be a userland mistake that is fixable. As far as we are aware, dom/on does the right thing OOTB for this use case of streaming rapid data entry to the server. @U050CJFRU if you want to dig deeper, i'd request a minimal repro in the form of a single file in a fork of the https://github.com/hyperfiddle/electric-fiddle, with no added dependencies (no datahike), just println on the server. I believe we will find that the println is called in the intended way without "data loss"
thanks @U09K620SG you might be right. I tried boiling it down to a minimal repro without extra deps and couldn’t find the issue yet. Planning to rewrite that part of the code which might help resolving the issue. I also wonder if this has to do with the way a datalevin database is watched. a while ago Leo suggesting using this https://github.com/lumberdev/tesserae/blob/master/src/tesserae/ui/electric_util.cljc#L115-L127 impl rather than e/watch. Does that still apply?
i don’t understand what that is working around
do you have the original thread with leo?
ok, I don't see how this could be related
oh, actually maybe it can be related
Ok i dont know if this is going to impact your issue, but I detect a minor correctness issue in the transact snippet from the other thread
i want you to wrap all calls to db/transact!
in e/offload
, like https://github.com/hyperfiddle/electric-xtdb-starter/commit/99d9aac82aba3c7d14a81ee928ef031ea776a22b
presumably that call can block for some period of time, and you are hitting it rapidly, this could cause a backup of blocking calls, which will block the electric server process
I wouldn't expect the missing e/offload to impact your issue (just slow down your app because each transact will block any queries from proceeding in parallel), but the datalevin async-watch locking workaround might have some deep interaction with this that i dont undertand
also the report of "data loss" is a hint, i don't have an explanation for that yet
a bunch of backed up blocking calls will be racing against new messages from network that queues up more blocking calls and we potentially desire to cancel stale calls, that is a complex interaction
the e/offload, by moving the d/transact! to a thread, makes it cancellable in the first place – without the m/via, i don't think the effect can be cancelled at all it just blocks until it suceeds
maybe somehow the wrong one is winning, i'd have to think a lot harder, but the point is – i see a potential interaction
The part that is cancelled is not the transact but a missionary task eval/eval-cell-task
that already runs using m/via
internally
https://github.com/lumberdev/tesserae/blob/master/src/tesserae/ui/sheet.cljc#L78-L96