@dborges @kevin.van.rooijen: Just catching up on the above discussion…
It sounds like there are some analogies between what you’re wanting to do and integrants suspend/resume mechanism. I wonder if you could hack something together using aspects of that mechanism.
Also I noticed you mentioned “frontend”. Obviously one difference between clojurescript and clojure is that clojurescript doesn’t really have runtime eval, consequently all the cljs needs to be compiled first; which kinda implies you’re requiring everything, and bits of integrant like ig/load-namespaces don’t make sense.
So wondering what you mean by “lazy loading”, how are you doing that?
Also what are modules in this context?? I’m guessing you don’t mean duct modules as IIRC they’re a pure clj thing.
I think lazy loading in this case means dispatching the events in the multimethods lazily
Since the event might trigger an HTTP request, for example (but Dax can probably elaborate 😄 )
ok — so not something based around something like requiring-resolve (which presumably isn’t available in cljs)
I wouldn't think so no. I assume all multimethods are required before compilation is started
But that's my assumption of the situation
yeah
having to use remove-method feels a bit icky though
It definitely is 😄
“nice” hack though 😁 (for some definition of nice)
But if you want to make integrant do something it's not meant to do
Then yeah 🤷
multimethods in clojurescript will never re-evaluate in production, so I don't see how this could break
Yeah I’ve definitely found integrant isn’t entirely suited for things like this. It’s good for static systems, but dynamic systems it’s always a bit of cludge.
I'm actually working on a more dynamic-ish implementation similar to integrant. But still a bit in hammock mode
Since I'm abusing integrant heavily at the moment (in production)
I could really use a more tailored solution for my use case
Integrant's dependency resolver is also very slow. If you have a large configuration it can take seconds te resolve
But again, these are things that Integrant wasn't really made for
Yeah definitely
I’ve got usecases where I want multiple phases for initialisation… e.g. I need a phase where some bits of the system are initialised first, e.g. a database is loaded with reference data, which is then validated, then after that the webserver is started.
I spoke to @dominicm about this topic a year or two ago, and I seem to remember him creating a more dynamic “integrant”; but I can’t for the life of me remember what it was called.
This maybe?
No docs though and hasn't been updated in a while, so that unfortunate
I don’t think that’s it
it had a pretty comprehensive readme
Hopefully he will enlighten us 😄
This is it: https://github.com/juxt/clip
Never used it though — though I seem to remember him creating it shortly after we spent a while discussing a more dynamic integrant. Unfortunately I never got around to having a play with it.
Thanks for the link
I'll check this out when I have time
Returning to the original question, and phased systems… I wonder if we really need a new integrant at all… perhaps just a few new defmethods…
e.g. in the same way ig/resume takes a config and an old system, we could have a new variant that took a config and a running subset of the system, and started the remaining bit… it would just call ig/init-key for anything not already running.
tempted to write this now — but got other stuff to do 😞
I guess you could do something like that, but you'd have to keep track of keys that have been initialized. Also if you initialize for a second time you will have 2 separate subsets. Sounds a bit like a pain to manage (in this use case)
A system only contains initialised keys, so the key diff between the remaining config and your previously initialised subsystem should give you that.
I might be misunderstanding your intent though
Sorry I don't have a ton of time to discuss this right now but for clarity, when I say lazy-load I mean we are loading a javascript file into the browser based on when a user takes some action which requires additional functionality. This JS file contains components which have dependencies which have already been initialized from the main bundle on page load