Teda já dělám spíš do včel, ale jak jsem tak listoval examply, říkal jsem si "tady se předávají jako data textové řetězce. Jestlipak by šlo předávat strukturovaná data / objekty / odkazy do databáze (pokud to má smysl)". A koukám že Node-RED přesně k tomuto používá JSON... díky za vysvětlivku.
Samotný nápad, že vlákna komunikují skrz fronty (etuda o producentech a konzumentech v partial meshi), ten je dost obecný. Svého času jsem takhle napsal nějaký protokolový konvertor / komunikační převodník...
Jinak v minulém tisíciletí nám ve škole vyprávěli o vizuálním modelovacím nástroji (diagramu) zvaném Event-driven Process Chain. Slouží to k modelování business procesů (analýza/design informačních systémů), tehdy nám o tom vykládali v souvislosti se SAPem. Je to podobné FBP spíš v rovině "základní myšlenky" = nikoli doslova, už třeba skladbou primitiv v grafu. Zjevně jiné patro "tvorby", ale pocit deja vu mnou cloumá...
Díky panu Tišnovskému za článek :-)
22. 4. 2022, 11:14 editováno autorem komentáře
Popravdě přemýšlím nakolik je toto podobné reactive streams https://reactivex.io/ , které nepoužívají vlákna, ale také jde o posílání zpráv skrz nějakou definovanou pipeline.
Předávání zpráv je relativně známý obecný koncept, takže jde hodně o detaily konkrétní aplikace.
Ano, FBP se puvodne objevilo v dobe jednojadrovych skalarnich CPU a potom to (mimo ridici techniku) usnulo. Probudilo se znovu v dobe vicejadrovych superskalarnich procesoru a zatimto goflow je jeden proces (z hlediska OS) + mnoho gorutin, je samozrejme mozne FBP pouzit o uroven vys a mit vic procesu, dokonce vzdalenych (takze klidne Kafka nebo nejake message brokery typu RabbitMQ atd. pro realizaci "bufferu").
Tedy jeden rozdil tam je - v klasickem FBP proste proces jen prijima data na "svem" portu a posila je na "sve" porty. To, jak data budou smerovana, uz proces neovlivni, taky ho to nema co zajimat. S message brokerem je to (muze to byt) komplikovanejsi, protoze je nutne znat topic.
Dřív jsem se o tohle paradigma dost zajímal a ze zajímavých nástrojů/jazyků co znám ho používají např. PurData/Max MSP, Faust atd. Nicméně přesně jak je v článku napsáno, něco dobrého to přináší a něčím to značně omezuje. Z formálních systémů se tomu blíží nejvíce popis pomocí petriho sítí. Těším se na pokračování.
21. 4. 2022, 13:03 editováno autorem komentáře
Akorát v tom Erlangu se nejedná o nějakou knihovnu nad obecným jazykem, ale o součást jazyka (syntaktické konstrukce na odesílání a příjem zpráv). Procesy tam nejsou jako vlákna operačního systému, ale interní tzv. odlehčené procesy, které si Erlang spouští vlastním plánovačem (shedulerem). Takže jich může být opravdu moc hodně, je laciné je vytvářet a mohou se spouštět tehdy kdy je třeba. (netřeba mít nějaký pool předforknutch vláken a různě je recyklovat).
Na Erlangu není zajímavý ten vlastní jazyk. I když je hodně vizionářský. Ale to runtime. Je rychlé a spolehlivé.
Z věcí co v Erlangu jsou už cca 30 let očekávám znovuobjevení např.
* spojování procesů (jeden proces ze skupiny spadne, shodí to celou skupinu, neboť je na něm závislá) a monitorování procesů (zhavarovaný proces je nahlášen zprávou dozorci). Z toho se pak dá udělat strom závislostí a supervisorů (nějaký proces spadne, tak se restartuje a případně to restartuje skupinu závislých procesů) - aplikace se pak stane odolnější proti chybám - chyba shodí a otočí jen to co je nutné, co na tom nezávisí to nesletí.
* imutable struktury - tady IT mainstream začíná uznávat, že to je dobrý nápad. Ale ještě pokud vím nezašel tak daleko, aby to byla přímo součást jazyka. To má význam při uvolňování nepotřebné paměti. Garbage collector je pak jednodušší a může být per proces místo jednoho velkého pro celý runtime. Takže Erlang nemá problém "stop the world". Viděl jsem velké problémy, které to na vytížených systémech v Javě způsobovalo. (ale nesleduji to, pokud je to už je vyřešené, tak pardon)
* tabulky s daty jako součást aplikace - pokud data a aplikace jsou v jednom procesu (z hlediska OS), tak přístupová doba pro hledání řádku podle indexu jsou jednotky mikrosekund. U meziprocesové komunikace s externí databází (obvykle přes sockety) to je bývá o 3 řády více.
* transparentní spojování více nodů do clusteru - v článku popsané zasílání zpráv jde dělat přes síť. Na ID procesu se pošle zpráva a je jedno, na kterém počítači ten proces běží. Z toho se pak dá postavit distribuovaná aplikace podle potřeby.
* změna kódu za běhu - to má Erlang udělané přímo v sobě. Viděl jsem jen něco podobného v Javě kde se to řešilo změnou názvu tříd. Kdy se kód generoval z nějakého metajazyka. Ale byl to takový hack.
No vetsina Javistu, co mluvi o immutable strukturach, vlastne ani nevi, o cem mluvi, to je zajimave. Tak reknete napriklad, jak by se v Jave resil (kdyz to "Java ma dlouho") napriklad takovy zakladni problem, jako immutable seznam nebo klidne i immutable pole (vektor). A ani nechci, aby to umelo structural sharing.
Neplanujem studovat co si ludia od Erlangu myslia o immutable, ak sa zhodneme na takejto definicii: Immutable data structure are data structures, like lists, arrays, sets etc., which cannot be changed, meaning that the values inside them can't be added, removed, moved or swapped.
Tak potom java.util.Collections:
unmodifiableCollection(...)
unmodifiableList(...)
unmodifiableMap(...)
unmodifiableSet(...)
unmodifiableSortedMap(...)
unmodifiableSortedSet(...)
Praveze vubec, beru z dokumentace*:
Note that changes to the backing collection might still be possible, and if they occur, they are visible through the unmodifiable view. Thus, an unmodifiable view collection **is not necessarily immutable**
* https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Collection.html#unmodview
Ak nerozumiete tomu ako funguje Java tak je to potom dost komplikovane. Ak vam z volania metody vratim immutable list nemate sa ako dostat k backing listu. To je iba upozornenie akym sposobom pracuje ta wrap vrstva ktora vam obali normalny list. Takze pokial si ho drzite u seba (ecapsulation) alebo ten smernik 'zabudnete/zahodite' nie je sposob akym sa da dostat k tomu backing listu.
Takze stale plati ze vrateny list je immutable.
- ta definicia je nezmyselna
- preco to tie 'pohlady' nesplnaju
- myslim ze v Jave dokazete bez problemov napisat take immutable aby splnali akukolvek definiciu immutable si vymyslite, existujuca implementacia v JVM je proste prakticka a postacujuca na pouzitie, to neznamena ze by sa v Jave pre pripad potreby nedala napisat aj uplne striktna implementacia immutable
Zkusím to vysvětlit. Zaprvé na "immutability" se musíme dívat jako na potenciálně velmi užitečnou vlastnost, nikoli jako na absenci "mutability".
Je to skutečně užitečná vlastnost, která nám mj. zaručuje, že se nám stav objektu pod rukama nezmění. A nejenom to, dokonce je zaručeno, že stav objektu můžeme číst bez zámků atd. - čím dál tím důležitější vlastnost, řekl bych. Prostě - máme objekt a můžeme s ním bez problémů a bez ohledu na okolní svět provádět všechny povolené operace.
A pokud je povolenou operací "získání podstavu", tak to opět můžeme udělat a interně se to může zajistit sdílením struktury, tedy obecně velmi rychle (jak jste zmínil někdy předtím: řetězce z toho velmi těží, protože spousta operací nad nimi se může obejít bez kopie/klonování).
A toto pohledy nemohou splnit ze dvou důvodů:
1) někdo může přidat/ubrat/zpřeházet prvky v té bázové kolekci
2) mohou se změnit stavy objektů ve vlastní kolekci
A současně to plně nesplňují ani immutable kolekce v Guavě:
1) mohou se změnit stavy objektů ve vlastní kolekci
To není jen takové "no a co, to je nějakej okrajovej příklad", protože to vlastně ničí všechny předpoklady, které o kolekcích máme. Například ten SortedSet - když změním objekt v kolekci, přeskládají se objekty v ní uložené? Pokud ano, není to immutable. Pokud ne, není to sorted set.
Dtto pro HashSet/HashMap - když změním objekt tak, že bude mít stajný klíč jako objekt jiný, bude se z kolekce vyhazovat? Nebo dostanu kolekci se dvěma objekty s totožným klíčem?
OK takze immutable chapeme rovnako. V com spocitava ta magia implementovat tu vasu rozsirenu definiciu immutable tak ako chcete. Neviem ako sa ma chovat ten immutable sortedset, zadefinujte si to a implementujte si to tak.
Ak chcete maj objekty immutable tak si ich tak urobte. Nie je to iba zakladna vlastnost 'bezneho' objektu v Jave ale implementovat to ide uplne jednoducho.
To cemu Pavle rikas "immutable" ale neni immutable. Pouzivas zde pohled javisty, ktery prevzal termin bez pochopeni toho, co skutecne znamena. Obzory muze rozsirit toto video https://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey/ (doporucuji, i kdyz budes dal psat v Jave, je to proste IMHO soucast obecneho IT vzdelani, i kdyz to muze znit akademicky. akademik vsak nejsem, jen prosta, ale dosti technicky znala namezni sila neboli human resource v zahranicni firme :/)
Nemusite sa obavat o moje teoreticke znalosti. Ja uplne presne chapem co je identita aj imutabilita aj co myslite 'svojim' immutable. Ibaze moj rozhlad je ale dalej nez je vasa akademicka definicia a dokaze pochopit aj kompromis ktory musite urobit aby sa to dalo aj prakticky vyuzivat.
Od vas je to trochu kratkozrake tvrdit ze MOJA immutabilita je ta prava a ta vasa je zla. Naviac ak do Erlangu bola akosi nutene namontovana pretoze prva implementacia bola postavena na Prologu a vlastne nepodporovala mutable struktury takze z nudze sme urobili top feature z funkcionalneho jazyka. Ak chcete definiciu immutable asi treba chapat a mat rozhlad, potom by ste sa dozvedeli ze "In some cases, an object is considered immutable even if some internally used attributes change" - si predstavte.
V konecnom dosledku potrebujete dat iba nastroje do ruk programatora a to ci potrebuje striktne immutable alebo iba 'read-only' alebo nejaky hybrid alebo ... nechat na neho. Ja tvrdim ze java ma absolutne postacujucu implementaciu immutable ktora je prakticky velmi dobre pouzitelna a pri pochopeni ako to funguje je to krasne pouzitelne aj pre rozne hybridne 'neakademicke' pristupy.
Vieme kde skoncili vsetky jazyky ktore sa pokusali o extremny purizmus.
" Vieme kde skoncili vsetky jazyky ktore sa pokusali o extremny purizmus."
Java je extremne puristicka, jen v jinem smeru. A mate pravdu, byla to slepa cesta, je postupne nahrazovana pragmatictejsimi jazyky jako Kotlin.
Ja s Vami souhlasim, ze mutable datove struktury jsou nekdy treba, ale vetsinou jen na low level veci, na ktere se JVM jazyky stejne nepouzivaji.
Podle me Erlang moc neznate, immutable datove struktury dovoluji vetsinu featur, ktere tu byly zmineny. Napriklad bezpecne prepinani kontextu v procesech (coroutinach) bez explicitniho await.
Nevim, jestli chapete, jak napriklad immutable mapy vnitrne funguji. Pri pridani prvku se nevytvori skutecna kopie, ale sdili se prvky z puvodni mapy. Vykonostni penalizace je mensi, nez na prvni pohled vypada.
Před pár lety, kdy jsem ještě pracoval na JVM, tak jsem měl docela dlouhou debatu na téma "immutable" v Javě. Nakonec jsme si myslím dobře vyjasnili (což je nejlepší vysvětlit na SortedSetu a SortedMapě nebo na prioritní frontě) terminologii a všimni si, že v Java docu prakticky nikde slovo "immutable" není (tedy kromě prázdných kolekcí, které jsou immutable jaksi z toho důvodu, že toto Java jako programovací jazyk ještě dokáže zaručit).
Raději se teď v Java docu používá slovo "unmodifiable", což má tu výhodu, že nemá až tak přesný význam :)
Právě, stejná situace jako s lidmi z Lighthousu, ale ti dělali původně v ObjC. Někde na webu je článek jednoho z nich o tom, jak ObjC ovlivnilo Javu (protože tam tito lidé přenesli mnoho myšlenek z ObjC). Java například původně neměla mít rozhraní. Taky některé třídy ve standardní knihovně jsou jen přepisem z ObjC.
Já immutable v Javě nepotřebuji, ono to totiž moc zajistit zatím nejde :-) Jen jsem Toma upozorňoval, že to nepochopení důsledků termínu immutable mezi vývojáři existuje.
Ale důvod, proč jsem to tehdy řešil s Oraclistama je ten, že jsem jakožto jeden z lidí okolo JVM (a tedy i dokumentace okolo JVM - tudíž i standardních knihoven) potřeboval zajistit kvalitu a jednoznačnost dokumentace. A nějaké házení termínem "immutable" například u takové struktury, jako je zmíněná SortedSet, SortedMap nebo prioritní fronta, by jen vedlo ke zmatení - a co hůř, k logickým chybám v aplikacích.
Ostatně zrovna v dokumentaci té Guavy to píšou alespoň v poznámce, když už ne v první větě, co se myslí tím "immutable" v Javě.
- spojování procesů -Má to dost podobné vlastnosti jako microservices
- immutable struktury - Dost se používá například v React aplikacích, ale má to svoje nevýhody, u komplikovanějších / hlubších struktur může být nutná normalizace atp.
- tabulky s daty jako součást aplikace - To se používá snad celou dobu, akorát ne vždy je takovou architekturu možné použít
- transparentní zasílání zpráv - Záleží, jestli do toho počítáte různé messaging systémy (Kafka atp.)
- změna ködu za běhu - Opět naprosto běžně používaná záležitost, silně zrychluje vývoj. Má to svoje limity, protože pokud má aplikace uložený stav a vy v té změně nějak upravíte jeho strukturu, tak se vám uložený stav samozřejmě neztransformuje, takže aplikace může dělat podívné věci. Ale s tím většinou počítáte.
Má to svoje limity, protože pokud má aplikace uložený stav a vy v té změně nějak upravíte jeho strukturu, tak se vám uložený stav samozřejmě neztransformuje, takže aplikace může dělat podívné věci.
Nevím zda samozřejmě - CL je možná letitý, ale součástí jazyka je automatické updatování objektů při předefinování jejich třídy, které aplikace může customizovat pro správnou transformaci.
> - spojování procesů -Má to dost podobné vlastnosti jako microservices
No však to také jsou "mikroservices", jen se to objevilo už v roce 1986, mnohem dřív, než začaly microservices být moderní.
A krom toho, každý ten Erlang proces potřebuje jen cca 300 B RAM na režii.
> změna ködu za běhu - Opět naprosto běžně používaná záležitost, silně zrychluje vývoj.
Jenže Erlang toto umí v produkci, včetně transformace dat (tu samozřejmě musíte napsat). V Erlangu je možné provozovat starý a nový kód současně (staré procesy doběhnou, nové už mají aktualizovaný kód).
Nadpis toho seznamu v původním příspěvku je "Z věcí co v Erlangu jsou už cca 30 let očekávám znovuobjevení", tedy můj výčet ukazoval, že ty věci nečekají na znovuobjevení, ale docela se používají.
Transformace dat za běhu je cool, na druhou stranu když se na to podívám inženýrsky, tak ve většině situací je přijatelnější službu prostě restartovat, než psát migrace (navíc) a řešit jejich QA.
Nicméně obojí řeší stejnou věc: jak provozovat oddělené úlohy na systému, který umí zpracovávat v každou danou chvíli jen jedinou instrukci (nebo třeba 4, ale na věci to nic nemění).
A navíc, dle dnešních definic jsou korutiny jsou obvykle založeny na kooperativním multitaskingu a mikroservices spoléhají na preempci a time slicing (= nemají explicitní yield).
Erlang je někde mezi.. nemá oddělený paměťový prostor jako procesy, ale neumožňuje čtení náhodné paměti. Má preempci na úrovni procesů, ale kooperativní plánovač.