Fork me on GitHub
#re-frame
<
2022-02-03
>
Arun15:02:44

Hi everyone, I was wondering if the only use case for async-flow-fx was for starting up an application in re-frame or if there were other use cases for it as well?

emccue16:02:15

Don’t use it. please

emccue16:02:50

for your startup, if its a complicated chain, just use a promise chain before your init event

emccue16:02:06

for “per-page-startup” use a different mechanism

Arun19:02:08

interesting, why not @U3JH98J4R

emccue19:02:52

We have a very large CLJS app that is still paying for that mistake

emccue19:02:40

Basically it does exactly what it says it does, but its a footgun waiting to happen

emccue19:02:06

The particular aspects you will usually fight are 1. It's one shot. If you change pages and want to run some setup again have fun 2. It implicitly sends you down the path of "events as helper functions" which gets super hard to debug and you never really handle error conditions

Arun19:02:55

but using one promise chain to set all this up means that you can’t as easily track the results through something like re-frame-10x

emccue22:02:29

yes. but the promise chain solution is only for stuff that is truly for the whole site

emccue23:02:38

everything else is better managed by storing the loading state of things in your db and managing what you do at each state explicitly

Joshua Suskalo17:02:22

So I'm currently reading reframe documentation and I'm really liking what I see so far. I do have one question: since all the re-frame code is in cljc files and can be loaded by the JVM, is there anything special I need to do to ensure I can have multiple re-frame sessions "in flight" at once if I'm doing server-side rendering? I noticed the TechAscent blog post https://techascent.com/blog/isomorphic-rendering.html mentioned needing to modify the library somewhat to enable this, but I was curious if that was still a requirement.

p-himik17:02:10

> multiple re-frame sessions "in flight" Not really clear what you mean, but assuming I understand you, I wouldn't use re-frame on the backend at all. That very same page says: > Unfortunately, `re-frame`'s JVM design is really only focused on light testing, and relies somewhat on the fact that JavaScript is single threaded. Both app-db and the event queue in re-frame are not a public API, so any attempt to circumvent the above would be unsupported, "here be dragons".

Joshua Suskalo17:02:02

the only stuff I see is an old fork https://github.com/techascent/re-frame/ although I think that it could pretty easily have a select set of commits rebased onto master and work.

Joshua Suskalo17:02:05

@U2FRKM4TW the point is to be able to use re-frame on the backend to pre-render the content and allow SEO and slow devices load the page content before the JS engine can render whatever is going on. I think that's a perfectly reasonable thing to want to do with re-frame since it already provides a cljc interface.

Joshua Suskalo17:02:25

And as mentioned in the post those non-public implementation details are currently implemented in a way that prevents this perfectly valid usecase without modification

Joshua Suskalo17:02:13

I'd be of the opinion that re-frame should create a clj-only public api to specifically allow constructing and tearing down re-frame sessions for the sake of pre-rendering.

p-himik17:02:12

I understand the need behind SSR. But re-frame was not built with that in mind. In fact, the team behind it uses it (or at least, was using it initially) for desktop CLJS applications. It is reasonable to want something, but I wouldn't expect something here, unless someone is willing to put in a lot of time in figuring out the right model that will work for everyone. And after a few years of closely monitoring this channel, SSR pops up incredibly rarely.

p-himik17:02:05

If both having SSR and using re-frame are hard requirements for you, perhaps something that evaluates JS and renders a page as a browser does would work instead. A couple of links here seem relevant although I haven't checked them myself: https://github.com/Day8/re-frame/blob/master/docs/External-Resources.md#server-side-rendering

Joshua Suskalo17:02:48

Yeah, I'm familiar with those. re-frame is not a requirement for me, just a nice-to-have. running a js engine on the server side though I'm not a fan of

dpsutton17:02:38

Would SSR with re-frame would require serializing an app-db?

p-himik17:02:21

It would require making every re-frame component thread-safe and isolated. Well, perhaps without sub/event/effect handler registries, if you're diligent enough with how you use those. Re-frame has both a global queue of events and a global app-db. It's easy to see how two concurrent requests from completely separate clients can mess things up, given the current state of affairs.

dpsutton17:02:11

It seems like it would otherwise anything pre-filled with data based on a subscription would immediately be blanked out on the client. So you’d have to send the app-db and the app-db can certainly hold non-serializable data

p-himik17:02:54

This issue is about a different thing but is still somewhat relevant: https://github.com/day8/re-frame/issues/137 Ah, yeah, you're right @U11BV7MTK, so the list of requirements grows.

dpsutton17:02:03

but p-himik it seems like your point is also really tricky. reframe uses single global defs. If you have 15 threads rendering html pages to send, that’s 15 threads all mucking about with those subscriptions

p-himik17:02:31

Indeed. That's why I'm saying that I wouldn't use re-frame on the backend, regardless of whether it's for SSR or not.

Joshua Suskalo17:02:21

I mean the solution to that is to just label them as ^:dynamic and then make some public entrypoint that binds them, sends some init event, does re-frame rendering until the event queue is empty, and then returns the current app state and the dom output for rendering to hiccup. I don't think that's too difficult in concept, and it's perfectly fair to say it's on the user to only use this when either all the app state can be serialized or to ensure that whatever can't be can easily be derived on client init.

Joshua Suskalo17:02:48

I'm not asking someone else to write this functionality, I'm just pointing out it seems like perhaps a usecase that shouldn't be ignored. I've taken a little interest in it, and if the re-frame devs show interest in this as a potential target, I may potentially be able to put in the work to build a proper public api for it and document it, since if I were to do that it would be for a website I'm already building anyway.

p-himik17:02:23

As can be seen from a few issues and the documentation page linked above, there definitely is some interest, just because some people want that too. And I find re-frame devs to be quite receptive of reasonably well thought-out concepts - FWIW, I've persuaded them to implement global interceptors without even having a PR for that. :)