Fork me on GitHub
#hyperfiddle
<
2023-02-24
>
Geoffrey Gaillard10:02:51

We are having an Electric Clojure Zoom session onboarding. We answer questions and help you solve issues. Anyone feel free to attend. DM me.

tatut14:02:26

why is Pending an exception? is it just due to convenience of using try/catch for that? having to wait for a call isn’t really exceptional or an error

Dustin Getz14:02:42

the semantics matched

2
Dustin Getz14:02:15

Its probably best to think of Electric as its own language, the idioms are different than Clojure

Dustin Getz14:02:14

Another example - in Clojure dynamic scope has a bunch of problems - it interacts badly with clojure's lazy collections, and also from a JVM concurrency perspective, bindings are threadlocals which have terrible operational semantics [Leo says: The reason why dynamic vars have terrible operational semantics and bad performance is the binding conveyance mechanism; there is nothing wrong with threadlocal which has well defined operational semantics and are also fast] but in Electric, dynamic scope doesn't have any of those problems, reactive bindings are a foundational compiler primitive and something we use extensively

tatut14:02:52

thanks for the explanation

🙂 2
xificurC15:02:27

another way to think about it - in electric everything has to have an initial value. What's the initial value of a server block that didn't come yet?

tatut15:02:35

coming back to my Pending loading indicator problem from yesterday, why is e/wrap needed for blocking JVM calls? results seem to work without it

tatut15:02:57

but it does show the catch block better if I add wrap

Dustin Getz15:02:21

blocking calls will block the event loop

Dustin Getz15:02:35

in a multi-user scenario all events will be blocked

Dustin Getz15:02:53

in our datascript demo we cheated and omit the e/wrap, we should fix it

tatut15:02:21

“all events” as in all events for all connected clients?

tatut15:02:05

but now that makes sense why the loading indicator didn’t work when I wasn’t using wrap

👍 2
xificurC15:02:31

it completely blocks the server side until it finishes

xificurC15:02:08

each client has their own server event loop, so not all clients

👍 4
xificurC15:02:29

e/wrap throws Pending so yes, it should improve the demo

Dustin Getz15:02:02

@U09FL65DK do they all have threads?

Dustin Getz15:02:36

@U11SJ6Q0K btw pull master , we fixed a regression related to Pending

🎉 2
Dustin Getz15:02:46

or i can publish a new version

tatut15:02:59

I’ll sync my fork

xificurC15:02:06

re threads, not sure

tatut15:02:37

one thing I liked about Phoenix LiveView (well many BEAM based systems) is the cheap processes and every connection having its own isolated process loop

tatut15:02:59

but perhaps the JVM isn’t as good (at least not before project loom)

xificurC15:02:38

You're right, BEAM has an advantage here. Loom will make this advantage smaller, but the JVM is still built for throughput

xificurC15:02:48

Either way electric needs to run async, so all blocking calls should be wrapped in e/wrap

tatut15:02:39

I could imagine wrap calls to be needed very often, perhaps a e/server-wrap convenience (kind of like async has go-loop)

👀 2
Dustin Getz15:02:20

yeah, could be. Maybe the Electric compiler can do stuff automatically, idk

tatut16:02:42

if you would always just wrap everything, would that cause problems? too much pendings even when you don’t need them

Dustin Getz16:02:03

one issue with wrapping everything is that calls like inc and println are indistinguishable from query-database , they are all synchronous and blocking

Dustin Getz16:02:51

so the cost of moving inc to a threadpool is paying thread communication overhead which dwarfs the cost of the actual inc

Dustin Getz16:02:42

one idea is to use statistical heuristics, the "Electric VM" can could maybe detect slow calls

tatut16:02:01

probably not worth it atm

👍 2
tatut16:02:13

but I was thinking about electric vs traditional apps

tatut16:02:24

usually you have some logging and middleware in backends

tatut16:02:08

could you do something like that in electric, like bind a call fn that takes a server side function as parameter to call it, wraps it handles errors and logging… even catches exception and shows “error topbar” on client

👀 2
Dustin Getz16:02:20

can you give me a concrete example of that in the context of one of our demos, say the todo list demo?

Dustin Getz16:02:52

Ok I understand now - you just want a easy way to log queries, intercept errors, and route errors to a banner

Dustin Getz16:02:18

i think you could code that today in userland in a few LOC with a higher order electric fn, or a macro

👍 2
tatut04:02:31

exactly that, I’ll try to experiment with that

tatut04:02:13

middleware that seamlessly handles both client and backend concerns would be 🔥

👀 2
tatut08:02:22

yes, it works great! it was easy to do

tatut08:02:29

I made a system I can call like (call. :some-service-name {:foo 42 :bar 123}) and it will invoke a service multimethod on the server in a wrap, and catch any errors… error is shown on client in an alert

👍 2
tatut08:02:54

I even added an m/observe that uses NProgress to show a generic top loader line

😁 2
Dustin Getz18:02:54

Deployment is coming, we have our demos running on fly .io $6/mo tier and performance is great so far, we tested Philadelphia <> Paris, will release the build scripts next week Rapid scrolling over node_modules from Philly to Paris with great performance for $6, it is a sight to behold

👍 18
💯 2