clojure-finland

Paavo Pokkinen 2023-05-24T19:16:39.279009Z

Olen tässä ihmetellyt kun aika simppeli staattisen sivuston generaattori clojurella, toki muutamilla dependencyillä, on uberjarrina 42MB. Jar-paketin kun purkaa, niin com.oracle.truffle on 33M, ja com.ibm.icu on 41M. Onko tämä mukana käytännössä kaikissa softissa aina? Saanko jarrin dependencyistä rakennettuna jonkun puun, jotta näkis mitä kautta nuo tulee mukaan projektiin? Pelkästään M1 macilla javalla main-funktioon saakka kestää 2.76s:

time java -jar target/generator.jar -asdf
2023-05-24 22:15:17.673:INFO::main: Logging initialized @1333ms to org.eclipse.jetty.util.log.StdErrLog
Invalid flag. Supported flags are -generate and -webserver.
java -jar target/generator.jar -df  2.76s user 0.14s system 205% cpu 1.418 total
Ja GCP:n cloud runissa kestää jotain 10 s docker-kontin ylösajo ja javan käynnistys. 😓 Mun depsit on:
{:deps {org.clojure/clojure             {:mvn/version "1.11.1"}
        com.taoensso/truss              {:mvn/version "1.9.0"}
        clj-http/clj-http               {:mvn/version "3.12.3"}
        hiccup/hiccup                   {:mvn/version "2.0.0-alpha2"}
        metosin/muuntaja                {:mvn/version "0.6.8"}
        floatingpointio/graphql-builder {:mvn/version "0.1.14"}
        stasis/stasis                   {:mvn/version "2.5.1"}
        optimus/optimus                 {:mvn/version "2023-02-08"}
        org.clojure/data.json           {:mvn/version "2.4.0"}
        ring/ring-jetty-adapter         {:mvn/version "1.8.2"}
        ring/ring-devel                 {:mvn/version "1.8.2"}
        ring/ring-spec                  {:mvn/version "0.0.4"}
        sitemap/sitemap                 {:mvn/version "0.4.0"}}
 :paths ["src" "resources"]
 :aliases {:project/run {:main-opts ["-m" "generator.core"]}
           :project/generate-sitemap {:main-opts ["-m" "generator.sitemap"]}
           :build {:deps {io.github.clojure/tools.build {:mvn/version "0.9.4"}}
                   :ns-default build}}}

Paavo Pokkinen 2023-05-24T19:28:28.267839Z

@teemu.kaukoranta Voi olla, joskin kirjoittaja lähinnä ajaa tuossa takaa docker-kontin layerointia jotta viimeinen layer on pienempi. Sinänsä en usko, että tuo käynnistysnopeuteen vaikuttaa paljoakaan, muuta kuin että käynnistys heti uuden deployn jälkeen voi olla nopeampi. Cloud runihan skaalaa kontit nollaan, jos requesteja ei ole 15 minuuttiin. Ja kun requesti tulee, käynnistetään uus kontti. Vähän niin kuin serverless siis.

Paavo Pokkinen 2023-05-24T19:31:54.658139Z

Lyhyen googlettelun perusteella graalVM vois olla ratkaisu, tosin näyttää aika työläältä saada toimimaan.

valtteri 2023-05-24T19:37:24.699599Z

Jos lähdet graal-tietä koluamaan niin täällä on hyvää lukemista https://github.com/clj-easy

juhoteperi 2023-05-24T19:41:48.050319Z

icu tekee mm. charset tunnistuksen, en ny muista tuleeko Muuntaja kautta, mutta se ei oo täysin pakollinen jos tietää että requestit on esim. aina utf8

juhoteperi 2023-05-24T19:42:05.130059Z

trufflea en muista nähneeni, deps tree näyttää mistä se tulee, arvaus ois truss tai graphql-builder

juhoteperi 2023-05-24T19:42:39.738589Z

clj --help sanoo mistä se tree tulee, oisko -Stree

juhoteperi 2023-05-24T19:43:42.468669Z

AOT auttaa käynnistysaikoihin, en nyt muista miten tools.build toimii niin en tiedä onko tuossa jo

Paavo Pokkinen 2023-05-24T19:44:10.536559Z

Näemmä truffle tulee tästä: https://github.com/magnars/optimus

juhoteperi 2023-05-24T19:45:28.322959Z

Tapauksesta riippuen voi olla vähän raskasta hoitaa noiden resurssien "optimointi" sovelluksen sisällä eikä build aikana

Paavo Pokkinen 2023-05-24T19:45:30.094759Z

Tosin, kun JVM alustaa niitä luokkia ajonaikana, niin jar-paketin koko ei taida suoraan korreloida käynnistysaikaan. Vaan se, missä koodipoluissa se alustetaan. Vois ehkä miettiä nuo tuotannon webserverin api-jutut ihan eri entrypointtiin / luokkaan noista lokaalin kehityksen web-serveristä.

Paavo Pokkinen 2023-05-24T19:46:45.308459Z

No joo, sinänsä me generoidaan vaan staattinen sivu. 🙂 Mutta on tuonne tarkoitus laittaa ainakin yksi formin submitin endpoint, ja joku preview-endpoint Contentfulia varten.

juhoteperi 2023-05-24T19:47:35.022699Z

css voi hoitaa ihan perus sass kääntäjällä, uglifyjs on turha cljs kanssa, noi cache headerit voi lisätä suoraan parilla rivillä koodia

ilmo 2023-05-25T08:57:40.124949Z

GraalVM saa nopeammaksi juu mut isoja paketteja tulee

ilmo 2023-05-25T09:01:57.331059Z

GraalVM ei ole mitenkään ongelmaton, pitää vähän varoa ettei depsut hajota buildia. Ei oo mikään mahdoton työmaa, mut selkee tradeoff.

juhoteperi 2023-05-25T09:05:30.396129Z

Toisaalta jos on staatisen sivun generaattori niin onko niin väliä jar koolla tai käynnistysajalla? kehittäessä sovellus voi olla käynnissä jatkuvasti jne.

ilmo 2023-05-25T09:08:43.281469Z

Mä kans kysyisin samaa. Devatessa on yleensä isoin ongelma, mut silloinkin systeemitkin voi spinnata päälle REPLin kautta.

ilmo 2023-05-25T09:10:17.438479Z

Jossain CLI-sovelluksessa käynnistysajalla on suuri merkitys, jonne sit graalvm istuu aika kivasti. Skriptauksessa myös babashka on ihan kohtuu nopea.

juhoteperi 2023-05-25T09:12:42.604399Z

Ehkä joku tapaus missä headless-CMS systeemi lähettää webhookilla päivityksen ja siitä spinnaa ylös joku lambda tms. ja pitäisi nopeasti saada päivitys ulos (tai ennen kaikkea ehkä jos preview tarvii saada näkyville nopeasti)

juhoteperi 2023-05-25T09:12:53.210049Z

Mut en tiedä tekisinkö Clojurella sellaista systeemiä välttämättä

ilmo 2023-05-25T09:19:09.520819Z

Lambdat onkin sit vähän oma juttunsa, niissä toki pystyy pyörittelemään clojurescriptiä, babashkaa tai https://github.com/candid82/joker.

viesti 2023-05-28T05:55:27.818809Z

Ehkä vähän AWS mainos, mutta AWS Lambdan JVM runtimessa on nykyään Snapstart -niminen feature, joka deploymentin yhteydessä käynnistää prosessin ja tekee siitä VM tason snapshotin, ja sitten requestia vastaanottaessa palauttaa tämän snapshotin. Nopeuttaa merkittävästi kylmäkäynnistystä JVM alustalla, myös Clojuren kanssa. Käytän yhdessä projektissa, jossa lambdassa reitit/muuntaja yms. kalustolla 8s kylmäkäynnistys nopeutuu ilman sen ihmeempiä optimointeja 500ms tasolle https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html Deploymenttiin tulee tosin pari minuuttia lisäkestoa ja pitää käyttää lambda versioita (checkpoint teko kytkettävissä lambda version teon yhteydessä päälle), mutta pystyy edelleen pitämään JVM:n mukana ja saaman nopean kylmäkäynistyksen ja sen jälkeen on edelleen se tuttu JVM kalusto pyörimässä, niin yksinkertaisti paljon native-imagen jälkeen buildiprosessiakin (native-image käännös ei sekään kauhean nopea ja resurssi-intensiivinen CPU ja muistin suhteen, riippuen tavukoodin määrästä).

👍 4
Paavo Pokkinen 2023-05-24T19:19:45.073489Z

On kyllä ollut positiivinen kokemus tämä Clojure näin muuten. Työkaveri, joka ei ole koskaan aiemmin clojurella mitään tehnyt, on nyt kuukauden päivät värkännyt tätä, enkä ole kädestä edes pitänyt kiinni. Tykännyt kovasti miten tehokkaasti ja vähällä koodilla asioita saa aikaan.

👍 1
valtteri 2023-05-24T19:31:55.508709Z

Jvm on aika läski ja hidas käynnistymään, kun sitä ei ole varsinaisesti suunniteltu one-off skriptien, vaan pitkään päällä pysyvien ohjelmien ajamiseen. Kikkailemalla senkin saa tosin aika pieneksi, mutta vaatii ekstratyötä.

valtteri 2023-05-24T19:32:44.674939Z

Mutta babashka tai clojurescript+node on toki myös vaihtoehtoja

Tuomas-Matti Soikkeli 2023-05-26T07:39:20.590909Z

mitenkäs ne graalvm ja native image hommat?

valtteri 2023-05-27T08:33:55.524619Z

Niitä ruodittiin tuossa ylempänä ketjussa myös hieman. 🙂 Eli se on ihan validi keino myös, mutta jos on riippuvuuksia, niin kaikki ei toimi välttämättä suoraan, tai ollenkaan. Babashkahan on käytännössä GraalVM:llä natiiviksi käännetty Clojure-tulkki + paristot.