This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-11-28
Channels
- # announcements (1)
- # aws (1)
- # babashka (41)
- # beginners (21)
- # biff (7)
- # calva (102)
- # cider (8)
- # cljs-dev (1)
- # clojure (8)
- # clojure-bay-area (2)
- # clojure-dev (30)
- # clojure-europe (40)
- # clojure-norway (52)
- # clojure-sweden (9)
- # clojure-uk (5)
- # clojurescript (15)
- # cursive (7)
- # data-science (1)
- # datomic (23)
- # events (1)
- # fulcro (9)
- # humbleui (23)
- # hyperfiddle (46)
- # introduce-yourself (1)
- # jackdaw (2)
- # jobs (2)
- # london-clojurians (1)
- # malli (13)
- # off-topic (8)
- # re-frame (36)
- # remote-jobs (1)
- # shadow-cljs (4)
- # specter (4)
- # squint (1)
- # transit (4)
- # vim (1)
Hvor ofte har dere fÄtt bruk for core.async
Channels i virkeligheten? :thinking_face:
Ganske mange ganger. Men det er ikke det fĂžrste verktĂžyet du strekker deg etter. Jeg bruker dem stort sett til Ă„ bygge "maskineri". Men som @emil0r sier - de kommer med skarpe kanter, sĂ„ bruk med mĂ„te đ
Jeg kom over https://github.com/unclebob/turtle-graphics/blob/main/src/turtle_graphics/turtle_commands.clj i dag og ble litt nysgjerrig pÄ det. "Hoi! Hva er dette? Dafuq betyr >!!
mon tro?"
En ting du ihvertfall skal ha i bakhodet er at du bÞr ha sÄ lite kode som mulig inne i go
-makroer. Den makroen skriver om koden din ganske grassalt, sÄ debugging er mer eller mindre umulig. SmÄ go-blokker som kaller pÄ "streite" funksjoner er Älreit. Og vÊre EKSTREMT paranoid pÄ feilhÄndtering (catch) og lukking+draining av kanaler, pass opp for ressurser som lekker osv.
Jeg er kjent med f.eks. RabbitMQ, Kafka og Azure Service Bus. Ved fĂžrste Ăžyekast og helt naivt fremstod det som noe i samme nabolag.
Har ikke helt oversikt. SÄ Alex skrev noe om loom, men hva det gjaldt vet jeg ikke. core.async har fÄtt skuffende lite kjÊrlighet de siste Ärene
NĂ„r man har et problem hvor en typisk ville brukt en "message queue" (RabbitMQ) eller "streaming dings" (Kafka), pleier Clojure folket Ă„ bruke core.async
istedenfor da, eller? Hvis det kun handler om "internleamikk" i sitt eget system, typ ikke kommunikasjon med eksterne applikasjoner.
Det Àr en implementationsdetalj Leif, men just nu sÄ Àr core.async bundet till en thread pool pÄ 8 threads
Det finns faktiskt tvÄ trÄdpooler. En Àr blocking (`<!` och alla andra bekvÀma funktioner). Men det finns en trÄdpool som startas med a/thread
som inte Àr begrÀnsad pÄ samma sÀtt (men heller inte riktigt Àr en del av CSP-modellen.
@leif.eric.fredheim core.async er ikke noen erstatning for kafka, nei. Men du kunne brukt core.async til Ă„ konsummere fra kafka
Jeg fÄr litt feelings av Erlang/OTP-aktig "actor model" ogsÄ nÄr jeg leser om dette, men sentralisert og i mye mindre skala (i Erlang kan man ha mange hundre tusen eller flere millioner "lettvektsprosesser" med en egen "innboks" som kjÞrer pÄ forskjellige fysiske nettverk/maskiner).
Core.async anvÀnder CSP, communicating sequential processes, vilket Àr samma filosofi som Erlang bygger pÄ. Dock har core.async inte i sig sjÀlv Erlangs processhantering, men det finns verktyg som byggt upp sÄdan med hjÀlp av core.async (lÀnk postade jag lÀngre ner)
Eksempler pÄ bruk av core.async fra mine prosjekter: Orkestrere asynkrone ting som skjer som resultat av endringer i filsystemet, parallellisere I/O, intern pubsub-kanal for Ä decouple deler av appen
core.async bÞr bare brukes i ett tilfelle: nÄr du skjÞnner at det du trenger er en maskin, ikke en funksjon.
og nĂ„r du er i en sĂ„ prekĂŠr situasjon, sĂ„ er det god hjelp Ă„ fĂ„ i core.async đ
Maskin som i "https://en.wikipedia.org/wiki/Finite-state_machine," typ?
ja, det er en okay mÄte Ä tenke pÄ det, men jeg vil si at det er mange mÄter Ä fÄ bruk for state machine-patternet ogsÄ utover core.async
Jeg oppdaget forresten https://clojure.org/about/state#actors som var opplysende for en tidligere Erlang-entusiast. > "Clojure is a functional language that explicitly supports programs as models and provides robust and easy-to-use facilities for managing identity and state in a single process in the face of concurrency. [âŠ] Clojure may eventually support the actor model for distributed programming, paying the price only when distribution is required, but I think it is quite cumbersome for same-process programming." Dette var en fin analogi: > "This is a world in which everyone sits in a windowless room and communicates only by mail."
Jeg tror dette ogsÄ er en indirekte referanse til Erlang/OTP: > "Also, because the set of functions is open, the set of actions supported by an Agent is also open, a sharp contrast to pattern matching message handling loops provided by some other languages." (https://clojure.org/reference/agents) Det virker som om Rich refererer ganske ofte til Erlang egentlig.
jag har anvÀnt core.async ganska mycket. Det har inte alls samma anvÀndningsomrÄden som tex Kafka eller RabbitMQ, tycker jag. Kafka Àr ju ett sÀtt att lösa persistens, vilket core.async inte Àr.
Core.async Àr som bÀst nÀr man behöver kod som vÀntar pÄ flera saker, eller ska vÀlja till exempel att ta frÄn en channel eller göra en time-out. Det Àr alltsÄ alt
som jag tycker Àr "the secret sauce" i core.async.
Det jag lÀrde mig mest av var att följa de hÀr kodexemplen: https://github.com/halgari/clojure-conj-2013-core.async-examples
Om man Àr intresserad av Erlangs OTP-modell finns detta: https://github.com/suprematic/otplike jag har aldrig sjÀlv anvÀnt det, men det anvÀnder Core.async för att sÀtta upp kommunikationen mellan olika processer. Centralt Àr att den har en trÀdstruktur med en översta processhanterare.
Det Àr ocksÄ sant att exceptionhanteringen helt enkelt inte fungerar i core.async. Ett sÀtt att lösa det Àr till exempel som pedestals interceptorer, som antingen kan returnera en contextmap eller en core.async-channel (som blir ungefÀr som ett promise, svaret i form av en contextmap förvÀntas lÀggas pÄ channeln nÀr det finns).
I interceptor-hanteringen (som i princip Àr en explicit callstack, eftersom ju JVM:en inte tillÄter att en jobbar med callstacken, som gjorts asynkron med core.async) omgÀrdar man hela hanteringen av interceptorfunktionen med en catch Throwable
, en lite bÀttre med core.match-baserad felhantering (som sÀgs vara inspirerad av IBMs sprÄk X10) samt hanterar scoopet för dynamiska variabler automatiskt: https://github.com/pedestal/pedestal/blob/master/interceptor/src/io/pedestal/interceptor/chain.clj
Denna mekanism har jag anvÀnt utanför requesthanteringen för att göra vissa sidoeffekter utanför sjÀlva requesthanteringen i pedestal - interceptorramverket Àr egentligen ganska generellt. Det Àr ocksÄ ganska lÄngsamt, jÀmfört med en JVM-stack. Dock krÀver inceptorerna mer tydligt en ingÄng och en utgÄng Àn vad "rÄ" core.async skulle kunna ge.
Ăven David Nolen har gett nĂ„gra riktigt bra exempel pĂ„ nĂ€r Core.async Ă€r vĂ€ldigt kraftfullt för vanliga praktiska problem: http://swannodette.github.io/2013/07/12/communicating-sequential-processes/
NÄ gikk det opp for meg hvor awesome Clojure er pÄ det som ofte kalles ELT eller ETL eller Data Engineering. Bedrifter bruker stort sett visuelle verktÞy som f.eks. https://www.snowflake.com/en/, https://www.matillion.com/technology-partners/snowflake, https://www.getdbt.com/product/what-is-dbt, https://airflow.apache.org, https://www.snaplogic.com, https://www.alteryx.com, https://www.tableau.com/products/prep, etc. Det kan vÊre "scheduled batch jobs" eller streaming. Et problem er at slike GUI-baserte "low-code verktÞy" produserer proprietÊre artefakter som er vanskelige Ä versjonere og samarbeide pÄ, og en er begrenset til "komponentene" som tilbys av disse verktÞyene. Channels og Transducers er jo helt nydelig til sÄnt (i tillegg til alt annet Clojure har Ä tilby). Man har ogsÄ native tilgang til f.eks. Hadoop, Spark og Kafka via Java interop. Jeg lurer pÄ hvorfor Clojure ikke er mer utbredt i denne nisjen. De fÄ som gjÞr ETL/ELT med kode pleier Ä burke Python eller Scala (for Ä fÄ tilgang til Java libs).
Eller kanskje mer mangel pÄ statiske typer nÄ til dags.
@leif.eric.fredheim https://github.com/slipset/guess-a-number/blob/master/src/guess_a_number/battle.clj er https://github.com/slipset/guess-a-number/blob/master/src/guess_a_number/core.clj implementert for to. Sistnevnte er kode som kom til verden ved at eldstemann hadde lĂŠrt seg âtenk pĂ„ et tallâ spillet, og sĂ„ skal man gjette hvilket tall det er. FĂžrstnevnte er dette spillet spilt av to ulike spillere i samme prosess. Aner ikke om det gir mening eller om det funker.