This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-07-04
Channels
- # announcements (10)
- # asami (6)
- # babashka (22)
- # beginners (44)
- # biff (1)
- # calva (8)
- # clj-kondo (13)
- # clojure (62)
- # clojure-art (1)
- # clojure-europe (27)
- # clojure-nl (1)
- # clojure-norway (19)
- # clojure-spec (19)
- # clojure-uk (2)
- # component (29)
- # datascript (1)
- # fulcro (9)
- # gratitude (2)
- # kaocha (6)
- # klipse (1)
- # luminus (16)
- # malli (9)
- # nbb (5)
- # off-topic (4)
- # reagent (5)
- # shadow-cljs (85)
- # spacemacs (1)
- # tools-deps (10)
- # vim (9)
- # xtdb (2)
hello, is there a way to measure how much time each component is taking to start? I'm trying to debug why some project here takes so long to start, and having the time for each specific component would be super helpful. the hard part of my case is that most components are part of external libraries, so changing their code to measure is painful
so far I got around by forking component and adding my measurement code there, but would be nice a way that doesn't require hacking the library
how long the start
fn (from Component/start) takes to run, for each component
this is what I did on my hack:
(defn- try-action [component system key f args]
(try (println "starting" component)
(time
(apply f component args))
(catch #?(:clj Throwable :cljs :default) t
(throw (ex-info (str "Error in component " key
" in system " (platform/type-name system)
" calling " f)
{:reason ::component-function-threw-exception
:function f
:system-key key
:component component
:system system}
t)))))
(the hack is back because this fn might be called during stop as well, but just a dirty hack to get it working for my case)
Sure, but I mean, take a step back, of your application is slow to start it is very unlikely that component start time meaningfully contributes to that
it actually is, from my debug I could find a single component taking 97s to start
from the 120s total
well, the slow ones are things that depend on external data, so they have to download things from the internet, it happens the perpetrator is doing a lot of downloading
so, this debug allowed me to pinpoint that component, and that's the gist of why I want something like that
Sure, well the component library has a function I forget the name of that basically maps whatever over the components in a system
But once you identify the components that are fetching things over the internet when starting, absolutely ditch them
its not that easy, because the components might implement other protocols other than the component one (and most on them in my case does) so wrapping that instance while forwarding every protocol is complicated
I think the ideal situation would be have sort of plugins/hooks support on component itself, so we could react to things like start/stop
You just use your own call using update-system like above in place of calling start on the whole system
Your can see it is what start-system does https://github.com/stuartsierra/component/blob/master/src/com/stuartsierra/component.cljc#L165 but just adding a call to time
generically
ah, makes sense, afk now, but will try whenI get back :)
ok, this works:
(defn start-measured [component]
(println "starting" component)
(time (component/start component)))
(comment
(time
(let [sys (system-config)]
(component/update-system sys (keys sys) #'start-measured))))