Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: BoneFlute 14. 10. 2019, 19:50:10

Název: Uváznutí v Aktor systému
Přispěvatel: BoneFlute 14. 10. 2019, 19:50:10
Zdravím.

Zkouším si jednoduchý Aktor systém. Celkem mi to jakože pěkně funguje, ale trošku jsem se zasekl na uváznutí.

Předpokládejme dva aktory A a B.
A -> B: kolik je hodin
B -> A: 19:41
A -> B: supr, díky
B -> A: není zač
A -> B: ok
B -> A: ok
A -> B: ok
B -> A: ok
A -> B: ok
B -> A: ok
A -> B: ok
...

Mohl by mi tu někodo poradit, jak se něco takového řeší? Třeba v Erlangu, systému Akka, nebo dalších?

Nechce se mi spoléhat na to, že ten aktor bude napsán správně. Rád bych tomu dodal alespoň základní ochranu. V "normálním" kódu se to dá trochu statistickou analízou podchytit. Na druhou stranu mé znalosti problematiky jsou omezené, a tak třeba existuje nějaké jednoduché řešení které dokáže víc.

Předem dík.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: limuhob 16. 10. 2019, 10:30:48
Moc nerozumím tomu problému. Jak ti vznikne ta nekonečná sekvence zpráv ok? Ty aktoři zprávu ok musí na základě něčeho zaslat.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 16. 10. 2019, 12:49:12
Ti aktoři jsou špatně napsaní. Když dostane správu "OK" tak na ni odpoví taky "OK". Prostě chyba.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Ondra Satai Nekola 16. 10. 2019, 13:00:50
Ti aktoři jsou špatně napsaní. Když dostane správu "OK" tak na ni odpoví taky "OK". Prostě chyba.

No a co si představuješ za řešení?
Název: Re:Uváznutí v Aktor systému
Přispěvatel: listoper 16. 10. 2019, 14:22:37
Ti aktoři jsou špatně napsaní. Když dostane správu "OK" tak na ni odpoví taky "OK". Prostě chyba.

Kacirska myslenka... :-)
Co na to napsat testy?
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Daniel Novotný 16. 10. 2019, 14:32:18
Není obecná detekce uváznutí ekvivalentní řešení halting problému?
Název: Re:Uváznutí v Aktor systému
Přispěvatel: registrovany_ava 16. 10. 2019, 14:40:17
No a jak vůbec víš, že to chování je špatně? Když si tu zprávu "ok" přejmenuješ třeba na "heartbeat", klidně by se to dalo považovat za pro některé scénáře korektní chování, např. testování živosti toho druhého aktora.

Souhlasím s příspěvkem dříve - napsat si na to testy.

Zdravím.

Zkouším si jednoduchý Aktor systém. Celkem mi to jakože pěkně funguje, ale trošku jsem se zasekl na uváznutí.

Předpokládejme dva aktory A a B.
A -> B: kolik je hodin
B -> A: 19:41
A -> B: supr, díky
B -> A: není zač
A -> B: ok
B -> A: ok
A -> B: ok
B -> A: ok
A -> B: ok
B -> A: ok
A -> B: ok
...

Mohl by mi tu někodo poradit, jak se něco takového řeší? Třeba v Erlangu, systému Akka, nebo dalších?

Nechce se mi spoléhat na to, že ten aktor bude napsán správně. Rád bych tomu dodal alespoň základní ochranu. V "normálním" kódu se to dá trochu statistickou analízou podchytit. Na druhou stranu mé znalosti problematiky jsou omezené, a tak třeba existuje nějaké jednoduché řešení které dokáže víc.

Předem dík.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: RDa 16. 10. 2019, 15:44:00
Rád bych tomu dodal alespoň základní ochranu.

Ochranu vuci cemu? Ja v prikladu zadne uviznuti nevidim, probiha tam aktivni komunikace.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 16. 10. 2019, 16:00:13
Ti aktoři jsou špatně napsaní. Když dostane správu "OK" tak na ni odpoví taky "OK". Prostě chyba.

No a co si představuješ za řešení?

Že to jakože "odhadne", že je tam chyba v komunikaci, a třeba to zařízne. Něco jako timeout. Nebo jako ta věc v databázi, která detekuje deadlocky.

Nemá-li to řešení, ok. Ale chtěl jsem se zeptat.

Moje aktuální úvaha směřuje k tomu, že budu sledovat komunikaci, a když se tam zopakuje vzor, tak to zaříznu.

Kód: [Vybrat]
Když A řekne "a" a B odpoví "b" a A odpoví "a", tak B vždy odpoví "b" -> konec
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 16. 10. 2019, 16:01:23
Ti aktoři jsou špatně napsaní. Když dostane správu "OK" tak na ni odpoví taky "OK". Prostě chyba.

Kacirska myslenka... :-)
Co na to napsat testy?

Úplně nevím, jak by to mohlo pomoct, ale nebráním se tomu. Jak?
Název: Re:Uváznutí v Aktor systému
Přispěvatel: registrovany_ava 16. 10. 2019, 16:40:59
Ti aktoři jsou špatně napsaní. Když dostane správu "OK" tak na ni odpoví taky "OK". Prostě chyba.

Kacirska myslenka... :-)
Co na to napsat testy?

Úplně nevím, jak by to mohlo pomoct, ale nebráním se tomu. Jak?

Je fakt, že aktory se testují blbě, protože aktor je vlastně izolovaná jednotka se skrytým mutable stavem a funkcí receive s typem Any => Unit (čti jako "spolknu cokoliv a možná udělám nějaký sideeffect"). Takže se při práci s aktory musíš prát s mutable stavem a navíc přicházíš o všechny kontroly, které normálně poskytuje statický typový systém. Možná proto taky např. Erlang statický typový systém nemá.

I tak ale nevidím problém v tom napsat alespoň test, který spawne dva aktory, nechá jednoho poslat druhému zprávu ok, a zkontroluje, že zpátky přišla právě jedna odpověď ok, pokud je to zamýšlené chování. Bohužel díky tomu skrytému mutable stavu není zaručené, že když to tak dopadlo jednou, dopadne to tak i podruhé.

Jen pro zajímavost, je dost problémů, které někdo řeší aktory, ale lépe se na ně hodí FRP. Tam naopak funguje statický typový systém bezvadně, obejde se to bez mutable stavu, takže se nad tím daleko líp uvažuje, je to víc komponovatelné. Nějaké shrnutí pro a proti jsem našel tady: https://cs.stackexchange.com/a/9042

Ale samozřejmě záleží na konkrétním problému, na spoustu věcí aktory jsou ideální řešení.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 16. 10. 2019, 16:45:58
I tak ale nevidím problém v tom napsat alespoň test, který spawne dva aktory, nechá jednoho poslat druhému zprávu ok, a zkontroluje, že zpátky přišla právě jedna odpověď ok, pokud je to zamýšlené chování. Bohužel díky tomu skrytému mutable stavu není zaručené, že když to tak dopadlo jednou, dopadne to tak i podruhé.

OK, ale tady se obávám, že neřešíš problém na který se ptám.

Jak otestovat aktor? To bych si snad i poradil.

Já se ale ptám na to, jak zjistit, případně otestovat, že v komunikaci mezi dvěmi aktory, které nemám pod kontrolou, nedojde k uváznutí. Přičemž samozřejmě se může jednat i o různé komunikace. Jednou je to ok -> ok, jindy done -> ok -> ok -> done... etc.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: registrovany_ava 16. 10. 2019, 16:57:29
I tak ale nevidím problém v tom napsat alespoň test, který spawne dva aktory, nechá jednoho poslat druhému zprávu ok, a zkontroluje, že zpátky přišla právě jedna odpověď ok, pokud je to zamýšlené chování. Bohužel díky tomu skrytému mutable stavu není zaručené, že když to tak dopadlo jednou, dopadne to tak i podruhé.

OK, ale tady se obávám, že neřešíš problém na který se ptám.

Jak otestovat aktor? To bych si snad i poradil.

Já se ale ptám na to, jak zjistit, případně otestovat, že v komunikaci mezi dvěmi aktory, které nemám pod kontrolou, nedojde k uváznutí. Přičemž samozřejmě se může jednat i o různé komunikace. Jednou je to ok -> ok, jindy done -> ok -> ok -> done... etc.

No, nejprve asi musíš definovat uváznutí. Jak poznáš, že nekonečná sekvence zpráv mezi aktory není korektní chování? Vždyť na tom, že si aktory posílají zprávy tam a zpátky není nic neobvyklého. Navíc právě díky tomu mutable stavu uvnitř nikdy nevíš, že je ta série zpráv skutečně nekonečná, můžeš mít uvnitř nějaký counter, který po tisíci iteracích přestane ok posílat, a zas to může být očekávané chování. Takhle asi narazíš buď na vágní definici uváznutí, nebo na Halting problem, jak zmiňoval někdo výše.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: listoper 16. 10. 2019, 17:23:03
I tak ale nevidím problém v tom napsat alespoň test, který spawne dva aktory, nechá jednoho poslat druhému zprávu ok, a zkontroluje, že zpátky přišla právě jedna odpověď ok, pokud je to zamýšlené chování. Bohužel díky tomu skrytému mutable stavu není zaručené, že když to tak dopadlo jednou, dopadne to tak i podruhé.

OK, ale tady se obávám, že neřešíš problém na který se ptám.

Jak otestovat aktor? To bych si snad i poradil.

Já se ale ptám na to, jak zjistit, případně otestovat, že v komunikaci mezi dvěmi aktory, které nemám pod kontrolou, nedojde k uváznutí. Přičemž samozřejmě se může jednat i o různé komunikace. Jednou je to ok -> ok, jindy done -> ok -> ok -> done... etc.

Ja sem tim myslel to, ze chovani toho aktoru by bylo pokryto unit testem.
Kazdeho zvlast.

A tim ze odstranis tu "proste chybu". A k uvaznuti nedojde.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Ondrej Nemecek 16. 10. 2019, 18:18:56
Aktorům sice nehovím, ale nepomohlo by prostě vědě, co aktor A a B ve skutečnosti dělají? Protože obecně na to snad ani nemůže být odpověď.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 16. 10. 2019, 20:22:20
No, nejprve asi musíš definovat uváznutí. Jak poznáš, že nekonečná sekvence zpráv mezi aktory není korektní chování? Vždyť na tom, že si aktory posílají zprávy tam a zpátky není nic neobvyklého. Navíc právě díky tomu mutable stavu uvnitř nikdy nevíš, že je ta série zpráv skutečně nekonečná, můžeš mít uvnitř nějaký counter, který po tisíci iteracích přestane ok posílat, a zas to může být očekávané chování. Takhle asi narazíš buď na vágní definici uváznutí, nebo na Halting problem, jak zmiňoval někdo výše.

No, momentálně jsem ve stavu kdy zjišťuju co se s tím dá dělat. Mnohé věci mi jsou jasné, mnohé ne.

Tak možná by šlo, v případě deterministické funkce tu chybu odvodit podle toho vzoru víše. U nedeterministické funkce jsem samozřejmě v háji.

Také jsem uvažoval, že bych to prostě jen výce vyhranil, aby to nebylo snadné, udělat cyklus. Třeba potvrzenka k tomu svádí. Takže udělat speciální typ zprávy, na kterou se neodpovídá.

A tak.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Jiří Havel 17. 10. 2019, 09:49:40
Tak možná by šlo, v případě deterministické funkce tu chybu odvodit podle toho vzoru víše. U nedeterministické funkce jsem samozřejmě v háji.
Determinismus toho moc neřeší. Ty actory můžou mít celkem složitý vnitřní stav. I pseudonáhodné generátory jsou deterministické a vzory se tam hledají dost blbě.

Periodicky se opakující vzor může být naprosto korektní chování. Představ si třeba komunikaci s nějakým senzorem.
Citace
Také jsem uvažoval, že bych to prostě jen výce vyhranil, aby to nebylo snadné, udělat cyklus. Třeba potvrzenka k tomu svádí. Takže udělat speciální typ zprávy, na kterou se neodpovídá.
Jo, pokud bude hlídač vědět, co tam má lítat, tak už se dá hlídat víc. Ale taky se to začíná blížít unit testům, které tu už pár lidí doporučovalo.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 17. 10. 2019, 14:47:46
Ale taky se to začíná blížít unit testům, které tu už pár lidí doporučovalo.

Ty unittesty byla evidentně rada z nepochopení. Tu jsem vyškrtl.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Jiří Havel 17. 10. 2019, 17:40:54
Ale taky se to začíná blížít unit testům, které tu už pár lidí doporučovalo.

Ty unittesty byla evidentně rada z nepochopení. Tu jsem vyškrtl.
Možná by stálo za to rozepsat důvody, proč tady unittesty nepomůžou. Mohlo by to tu diskuzi trochu posunout.

Osobně nevidím nějaký zásadní rozdíl mezi specializovaným hlídačem nějakého protokolu (musí být specializovaný, protože obecně tam může lítat opravdu cokoliv) a specializovaným testem nějakého rozhraní. Oboje kontroluje, jestli ta komunikace odpovídá nějaké předloze, jen to kontrolují jindy.

Nebo jsou ty aktory nějaké zprasené produkty třetí strany bez podpory, zdrojáků a naděje?
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 17. 10. 2019, 18:02:46
Ale taky se to začíná blížít unit testům, které tu už pár lidí doporučovalo.

Ty unittesty byla evidentně rada z nepochopení. Tu jsem vyškrtl.
Možná by stálo za to rozepsat důvody, proč tady unittesty nepomůžou. Mohlo by to tu diskuzi trochu posunout.

Osobně nevidím nějaký zásadní rozdíl mezi specializovaným hlídačem nějakého protokolu (musí být specializovaný, protože obecně tam může lítat opravdu cokoliv) a specializovaným testem nějakého rozhraní. Oboje kontroluje, jestli ta komunikace odpovídá nějaké předloze, jen to kontrolují jindy.
Jen jsem se chtěl vyhnout uváznutí v cargo-cultu.

Odhlednuto od toho prakticky souhlasím. Teď řeším jak na to. Co a jak můžu zajistit. Jak mohu definovat protokol. Nebo zda validovat vlastní aktor. Co ještě dělat, a co už se nevyplatí.

Zatím uvažuju o tom, že připravím API tak, abych vývojáři dosažení uváznutí co nejvíc zkomplikoval. I zde se mohu ptát, jak.

Nebo jsou ty aktory nějaké zprasené produkty třetí strany bez podpory, zdrojáků a naděje?
Naopak. Jsem v okamžiku návrhu. Všechnu je zelené a krásné. Ale ty aktory může (bude moct) napsat kdokoliv.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: registrovany_ava 17. 10. 2019, 20:35:42
Naopak. Jsem v okamžiku návrhu. Všechnu je zelené a krásné. Ale ty aktory může (bude moct) napsat kdokoliv.

Hmm, a máš k tomu nějaké zadání? Třeba bychom se nad tím návrhem, vzory co omezí uváznutí atp. mohli zamyslet kolektivně..
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Jiří Havel 17. 10. 2019, 22:35:40
Naopak. Jsem v okamžiku návrhu. Všechnu je zelené a krásné. Ale ty aktory může (bude moct) napsat kdokoliv.

Hmm, a máš k tomu nějaké zadání? Třeba bychom se nad tím návrhem, vzory co omezí uváznutí atp. mohli zamyslet kolektivně..
Tak nějak. Zatím víme akorát to, že nějací nám neznámí programátoři budou psát nějaké blíže nespecifikované agenty. A ti agenti si budou mezi sebou posílat nějaká nám neznámá data. Jediné, co zatím víme, je že se to nebude testovat, páč to je kargokult.

Kdo ty agenty bude psát? Programátoři, poloprogramátoři, nebo cvičené opice? A v čem?
Co ti agenti budou dělat? Jaká konkrétní data si mezi sebou budou posílat?
Co ten komunikační protokol musí umět? Má být synchronní nebo asynchronní? Posílají si agenti zprávy přímo, nebo dávají obecné požadavky? Co latence a propustnost? Nestačí na to něco odladěného typu ZeroMQ?
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 18. 10. 2019, 00:11:49
Jediné, co zatím víme, je že se to nebude testovat, páč to je kargokult.

Tímto přístupem se na to možná rovnou vykašli, ne?
Název: Re:Uváznutí v Aktor systému
Přispěvatel: uetoyo 18. 10. 2019, 00:14:52
To vypadá, že máš spíš jakýsi "filozofický" problém. Ono asi jasné zadání není nebo na něj vlastně ani aktory použít není třeba. Ale proč si to nekomplikovat že?
Název: Re:Uváznutí v Aktor systému
Přispěvatel: uetoyo 18. 10. 2019, 00:16:59
Citace
Tímto přístupem se na to možná rovnou vykašli, ne?

No to sis vlastně odpověděl ne?  ;)
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 18. 10. 2019, 00:35:54
Naopak. Jsem v okamžiku návrhu. Všechnu je zelené a krásné. Ale ty aktory může (bude moct) napsat kdokoliv.

Hmm, a máš k tomu nějaké zadání? Třeba bychom se nad tím návrhem, vzory co omezí uváznutí atp. mohli zamyslet kolektivně..

Aktory jako služby, poskytující data i poskytující výpočty. Aktor jako klient se bude dotazovat jiných aktorů. Libovolný aktor může poslat dotaz libovolnému jinému. Zpráva vede přes prostředníka, který schraňuje zprávy, a pak je předává adresátům. Aktor dostane zprávu, podle ní vykoná svou úlohu - sám, nebo deleguje na jiného. Prostředník pošle zpět zprávu: zpráva uložena, zpráva vyzvednuta.

Zprávy coby komunikační protokol mám zatím bez pravidel. V dalším kroku bych rád nějaký formální jazyk typu KQML.

Tedy jak vidno, není to nic světoborného. Taky tam v tom zadání nejsou žádná zvláštní omezení. Jakékoliv postřehy vítám.

Pointa je, že jsem teda napsal první prototyp, a hned jsem si ho zacyklil. Tedy nejde mi o to, že by to muselo být vysloveně neprůstřelné jen by to snad nemuselo být tak snadné to rozbít.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: gill 18. 10. 2019, 09:01:47
Mě by také zajímalo, co tím řešíš, dvousměrná komunikace je v asynchronním programování často anti-pattern. Jak už tu někdo napsal, konečnost výpočtu obecně zjistit nelze. Ale nekonečná smyčka je u většiny reálných programů to co chceš, z toho příkladu není jasné, kde je chyba. Mezi posíláním zpráv to klidně může vykonávat něco užitečného. Bez konkrétního zadání je diskuze zbytečná.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: registrovany_ava 18. 10. 2019, 09:02:48
Aktory jako služby, poskytující data i poskytující výpočty.

Abychom zkusili trochu utéct XY problému, co to má vlastně dohromady dělat? K čemu ta aplikace slouží? Jaké jsou požadavky na rozšiřitelnost, distribuovanost, odolnost proti výpadkům sítě, konzistenci, živý upgrade atp.? To jsou asi otázky relevantní pro aplikaci, pro kterou se někdo rozhodne použít aktory..
Název: Re:Uváznutí v Aktor systému
Přispěvatel: gill 18. 10. 2019, 09:09:57

jak z toho obecného popisu máme zjistit, proč dochází k zacyklení? nechceš ukázat konkrétní kód?
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Jiří Havel 18. 10. 2019, 09:18:27
Jediné, co zatím víme, je že se to nebude testovat, páč to je kargokult.
Tímto přístupem se na to možná rovnou vykašli, ne?
:o To byla narážka na tvůj příspěvek :
Jen jsem se chtěl vyhnout uváznutí v cargo-cultu.
Jo a
Aktory jako služby, poskytující data i poskytující výpočty. Aktor jako klient se bude dotazovat jiných aktorů. Libovolný aktor může poslat dotaz libovolnému jinému. Zpráva vede přes prostředníka, který schraňuje zprávy, a pak je předává adresátům. Aktor dostane zprávu, podle ní vykoná svou úlohu - sám, nebo deleguje na jiného. Prostředník pošle zpět zprávu: zpráva uložena, zpráva vyzvednuta.

Zprávy coby komunikační protokol mám zatím bez pravidel. V dalším kroku bych rád nějaký formální jazyk typu KQML.

Tedy jak vidno, není to nic světoborného. Taky tam v tom zadání nejsou žádná zvláštní omezení. Jakékoliv postřehy vítám.

Pointa je, že jsem teda napsal první prototyp, a hned jsem si ho zacyklil. Tedy nejde mi o to, že by to muselo být vysloveně neprůstřelné jen by to snad nemuselo být tak snadné to rozbít.
není zadání. Tohle je teoretický popis úplně obecného actor systému. Pokud ty actory můžou dělat a posílat cokoliv, tak nemáš co hlídat. Jakékoliv chování může být správně.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: mudrlant 19. 10. 2019, 20:11:18
K čemu slouží zprávy OK?

Pokud Vám aktor B poskytl odpověď, proč mu znova posíláte další potvrzovací zprávy?
Pokud je to proto, aby si i aktor B byl jist, že odpověď došla, tak to je cesta do pekel - donekonečna se budou navzájem ujišťovat o tom, že si navzájem odpověděli.

V této konkrétní komunikaci je aktor A ten, kdo má zájem na výsledku a proto postačí, pokud od B dorazí odpověď.
B nemusí vědět, zda odpověď došla. Pokud by nedošla, tak ho A sám znovu upozorní.
Pokud A tedy nedostane v nějakém očekávaném časovém limitu odpověď, může se pokusit poslat požadavek znovu.

V reálném případě, kdyby požadavek měnil výrazným způsobem stav aktora B, a tudíž znova vykonaný požadavek by nežádoucím způsobem změnil opět stav B, řeší se to např. tak, že A očísluje své zprávy.
Pokud A tedy pošle znovu zprávu se stejným číslem, B už ví, že na ten požadavek odpověděl a pošle např. tutéž nacachovanou odpověď, aniž by měnil svůj stav.

Předpokládejme dva aktory A a B.
A -> B: kolik je hodin
B -> A: 19:41
A -> B: supr, díky
B -> A: není zač
Název: Re:Uváznutí v Aktor systému
Přispěvatel: tacoberu 19. 10. 2019, 22:41:02
Sledovat opakující se vzory by mohlo fungovat. Ale je třeba - jak už to někdo uváděl - rozlišit chybu od záměru. Napadají mě dvě metody, ale určitě se najdou další:

1. Pokud je opakování až po nějaké době, pravděpodobně to nebude chyba ale záměr.
2. Pokud má být záměrem opakující se vzory, tak může pomoct, aby to ten objekt musel nějak explicitně vyjádřit, například speciálním druhem zprávy, nějaký příznakem, hashem, něčím.

Rozhodně to ale není neprůstřelné, to je snad jasné. Mohou stále vznikat chyby, ale díky bodu dva by neměl být problém opakovat zprávy když je to potřeba.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Ondrej Nemecek 20. 10. 2019, 03:05:23
Předpokládejme dva aktory A a B.
A -> B: kolik je hodin
B -> A: 19:41
A -> B: supr, díky
B -> A: není zač

IMHO je čisté řešení rozšířit zprávy OK na několik zpráv s tím, že některé zprávy budou terminální (konečné) a při jejich obdržení se ukončí komunikační transakce. Pokud jde o nějaký systém pro výpočty, pak budou aktoři asi nějací workeři. Ti workeři se budou nalézat v různých stavech a zprávy budou emitované při změně jejich stavu. Na odběr zprávy se budou moci registrovat další workeři, zajišťující třeba navazující výpočty. Pak si lze nakreslit všechny stavy, které může výpočet mít (všechny výpočty mohou mít buď totožnou množinu stavů anebo se množina stavů může odlišova podle prováděného výpočtu). Pokud jsou známy všechny stavy, lze si znázornit povolené přechody mezi těmi stavy a z toho lze pak vidět, kde vzniká cyklus a zda ten cyklus je žádoucí. Pokud žádoucí není, napojí se do cyklu exit vedoucí na nějaký terminální stav - například při dosažení nějakého čítače, nebo při překročení časového timeoutu apod.

V případě že jde o komunikaci jen dvou aktorů, je situace podobná. Pokud je vyžadováno potvrzení, jde o transakční chování a to opět znamená držet stav a vyřešit všechny možné okrajové situace (latence při přenosu zpráv, zprávy přijdou v opačném pořadí, zpráva přijde poškozená, duplicitně nebo vůbec, dojde pamět k držení stavu, je nutno řešit životnost stavu, ... atd).

Vždy je dobré se inspirovat v reálném světě - jak si zprávy předávají lidé s jednosměrnou vysílačkou? Používají konvenční signalizaci pomocí slov jako: přepínám... opakuji... rozumím... konec. Taky se lze podívat na síťové komunikační protokoly s handshakem, s retransmisí... Nebo se podívat na oběh dokumentů na úřadě - jsou tam také lhůty pro reakci, je určeno kdo to má všechno a v jakém pořadí schválit a orazítkovat, je tam lhůta na promlčení atd. - dokonce tam může dojít i k tomu zacyklení :-D

Zpátky k jednoduchému případu hodin. Místo OK - OK bude víc potvrzovacích zpráv rozlišujících, kdo co potvrzuje. Tím cyklus zmizí - vznikl pouze nedostatečným rozlišením zpráv. Například:

Citace
A->B: kolik je hodin?
B->A: je 10.30h
A->B: potvrzuji přijetí času 10.30h
B->A: díky za potvrzení, transakce dokončena

Pokud A nepotvrdí přijetí, může B poslat odpověď znova:

Citace
...
B->A: opakuji, je 10.30h
A->B: potvrzuji přijetí času 10.30h
B->A: díky za potvrzení, transakce dokončena

Nemá smysl, aby A ještě dál potvrzoval, že dostal od B potvrzení o tom, že A obdržel čas, na který se Bčka ptal.

U distribuovaných transakcí to může být složitější, tam může několik uzlů potvrzovat různé skutečnosti a teprv při splnění všech požadovaných podmínek dojde k uplatnění výsledné akce. Pokud budete mí ale výpočetní grid a budou mezi výpočty závislosti, budete to asi také řešit.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 20. 10. 2019, 14:19:39
...
...

Díky za cenný příspěvek.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Mirek Prýmek 20. 10. 2019, 20:03:52
Přemýšlel jsem, co ti na to napsat, a nakonec budu asi spíš stručnej. Jestli se v některým bodě trefím, můžem o tom třeba diskutovat šířejc.

1. Velice pravděpodobně řešíš pseudoproblém. Zapomeň úplně na aktory a převeď si to na tenhle dotaz:

Učím se céčko a není mi jasný, jak zamezit tomuhle:

Kód: [Vybrat]
int f() {
  return g();
}
int g() {
  return f();
}
Nechce se mi spoléhat na to, že ty funkce budou napsány správně.

Odpověď je stejná jako tvůj dotaz k Erlangu/Akka/... - nezaručuje se to obvykle nijak (v přísném, matematickém smyslu). Nepřímo je to totiž zaručeno tím, že kód má nějakou logickou strukturu a smyčka ve volání dost pravděpodobně znamená nějaký designový problém.

2. Vyjadřuješ se (z mýho pohledu) dost nejasně. Buď svoje myšlenky jenom (mně) nesrozumitelně vyjadřuješ, nebo je problém hlubší a o věci i přemýšlíš ze špatného úhlu pohledu.

V praxi to prostě bývá tak, že aktor implementuje nějaký kontrakt/protokol/API/... (je jedno, jak tomu chceme říkat) a ten obvykle bývá velice jednoduchý, mj. právě proto, aby bylo zřejmý, jestli aktor dělá to, co dělat má, dlo se to testovat, a zároveň to, co dělat má, nebyl nějaký nesmysl.

Úplně polopaticky: typicky actor implementuje třeba pattern request-response. Pošleš mu číslo a on ti vrátí jeho dvojnásobek. Není tam co řešit. Buď vrátí správný číslo a je to ok, nebo nevrátí a něco je blbě. Víc nad tím není co dumat.

Poučení: ujasni si, co má actor dělat, jaké má stavy (popř. jestli vůbec má stavy) a jakým komunikuje protokolem. Pokud chceš garantovat nějaké vlastnosti protokolu, uvažuj nad ním jako nad protokolem a úplně (pro tu chvíli) zapomeň na actory.

Poučení 2: Typicky čím míň má protokol omezení, tím míň jeho vlastností jsi schopen garantovat. A naopak. Snažit se dumat nad obecným protokolem, kde může docházet k čemukoli, moc nedává smysl. Jenom se v tom utopíš a nikam se nedostaneš.

3. Pokud jdeš králičí norou ještě o kousek hloub, skutečně v Erlang světě nastává problém podobnej tomu, co popisuješ. Je způsobenej tím, že pokud je actor stavový (což typicky je), pak má nutně jenom jedno vlákno (v úplně obecném smyslu "vlákno výpočtu", ne nutně OS vlákno apod.). Takže pokud máš komunikaci stylem A->B->C a ta komunikace je synchronní, tak dokud C neodpoví, A nemůže vyřizovat žádné další požadavky (např. X->A). Z toho taky plyne, že pokud se ti tam objeví komunikace A->B->A, dojde k deadlocku.

Je to principiálně dost nepříjemná věc, ale řešení je velmi stupidní, ehm. teda "pragmatický": každá komunikace má timeout. Problem solved :)

----

Vím, že neodpovídám přesně na dotaz, ale snad jsem se trochu trefil do něčeho, co tě může posunout. Jak jsem říkal, jestli chceš, můžem o tom trochu podebatovat, moc rád pomůžu, pokud budu schopen. Erlang je moje láska, takže mi dělá radost, že se tímhle světem někdo zabývá :)
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Mirek Prýmek 20. 10. 2019, 20:13:35
každá komunikace má timeout. Problem solved :)
Tady bych asi ještě jednou zdůraznil: každá synchronní komunikace. Tj. odešlu požadavek a čekám na odpověď, mezi tím žádné další požadavky nepřijímám ani neodesílám.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 20. 10. 2019, 23:16:35
Díky za příspěvek.

1. Velice pravděpodobně řešíš pseudoproblém. Zapomeň úplně na aktory a převeď si to na tenhle dotaz:

Učím se céčko a není mi jasný, jak zamezit tomuhle:

Kód: [Vybrat]
int f() {
  return g();
}
int g() {
  return f();
}
Nechce se mi spoléhat na to, že ty funkce budou napsány správně.

Odpověď je stejná jako tvůj dotaz k Erlangu/Akka/... - nezaručuje se to obvykle nijak (v přísném, matematickém smyslu).

Ano, takhle se klidně můžem bavit.

Když napíšu takovýto kód v Cčku, co se stane. Spustím to, a process bude vesele vyžírat prostředky, dokavad ho něco nezabije. Domnívám se, že nemůže nastat situace, že jsem si tím zasekl počítač, a můžu ho vyhodit.

V případě Aktorového systému jsem na tom podobně. Vzhledem k tomu, že to může být třeba přes vícero počítačů, tak když tam někdo zanese nějakou chybu, tak já nechci aby mi to všechno lehlo popelem. Zajímalo by mě to něco. Zajímalo by mě, jestli tomu můžu nějak zabránit. Ne absolutně, ne úplně. Ale alespoň trochu.

(Přičemž beru v potaz, co jsi k tomu už napsal. Jen se snažím vysvětlit svůj dotaz, když se evidentně tak blbě vyjadřuju.)
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 20. 10. 2019, 23:55:56
uvažuj nad ním jako nad protokolem

Tohle je dobrej hint.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Mirek Prýmek 21. 10. 2019, 06:29:40
Když napíšu takovýto kód v Cčku, co se stane. Spustím to, a process bude vesele vyžírat prostředky, dokavad ho něco nezabije. Domnívám se, že nemůže nastat situace, že jsem si tím zasekl počítač, a můžu ho vyhodit.
Úplně prakticky ne. Ten proces vyžere jedno jádro na 100% a poběží pořád, dokud ho nezabiješ ručně. Systém nemá důvod ho zabíjet, protože nezjišťuje, jestli proces dělá něco užitečného, nebo ne. Z pohledu systému ten proces není ničím divný, nenárokuje si pořád další a další prostředky, prostě jenom běží, na čemž není nic špatného (porovnej s odpověďmi kolegů výš, které říkají "na takové komunikaci není nic špatného").

A přesně to je pointa téhle analogie: přistupuješ k situaci "symptomaticky". Dělá ten proces, co dělat má? Ok, není co řešit. Nedělá? Zabiješ ho a budeš debugovat. Žere víc CPU než bys očekával? Zabiješ ho a budeš debugovat. Žere víc a víc paměti? Asi je tam memory leak. Zabiješ ho a budeš debugovat.

Žádná předběžná analýza kódu se v tomhle případě prostě nedělá. Program se spustí a až při běhu se zjišťuje, jak se chová. Ne, že by to bylo kdovíjak elegantní, ale je to pragmaticky nejlepší řešení.

V případě Aktorového systému jsem na tom podobně. Vzhledem k tomu, že to může být třeba přes vícero počítačů, tak když tam někdo zanese nějakou chybu, tak já nechci aby mi to všechno lehlo popelem. Zajímalo by mě to něco. Zajímalo by mě, jestli tomu můžu nějak zabránit. Ne absolutně, ne úplně. Ale alespoň trochu.
Tady mě zaujalo to slovo "všechno". Actor systém musí být udělaný tak, že jednotlivé actory jsou opravdu nezávislé. Takže nejhorší, co se ti může stát, je, že jeden actor (A) přestane fungovat. A případně ta jeho nefunkčnost způsobí nefunkčnost aktorů, které na něm závisí (B,C). V žádném případě by se ale nemělo stát, že přestane fungovat "všechno", zejména ne actor D, který s A ani B a C vůbec nekomunikuje.

Jak to zjistíš? No úplně stejně jako v té analogii: symptomaticky. Systém prostě přestane dělat to, co dělat má, a ty se budeš pídit po příčině. Žádnou větší vědu v tom nehledej, KISS! :)

Takovej nejjednodušší, ale velmi účinej způsob, jak takové situaci "předcházet", je mít u každého actora funkci/endpoint/... ping, a pravidelně pomocí nějakýho monitoringu kontrolovat jeho živost. Jinej možnej způsob je kontrolovat jenom vnější funkce systému (to, co tě jediný ve finále zajímá, je, jestli funguje systém jako celek - jestli poskytuje okolnímu světu to, co poskytovat má).

V Erlang světě se ale ten ping na každého actora (AFAIK) nepoužívá - není to prostě potřeba, protože to, čeho se bojíš, se moc často neděje a když se to stane, tak se to velmi rychle objeví. Ty důvody, proč se to neděje, jsou (jak jsem psal výš) spíš designové, než jakékoli jiné.

Jen se snažím vysvětlit svůj dotaz, když se evidentně tak blbě vyjadřuju.)
Neber si to vůbec osobně. Jenom jsem chtěl říct, že přesný definování problému pomocí adekvátních pojmů, je obvykle polovina řešení problému, však to znáš. Plavání v nejasných definicích a mlhavých problémech většinou nikam nevede...

---
P.S. Jak jsem tohle psal, tak mě napadlo, jestli náhodou se na tohle všechno neptáš proto, že zkoušíš napsat ten vlastní actorový systém (tj. tu vlastní infrastrukturu si píšeš sám). Pokud je to ten případ (nepoužíváš Erlang, Akka, ...), tak to určitě řekni, protože to by dost měnilo situaci. V tom vlastním systému je totiž potřeba dodržet pár věcí, které nejsou moc intuitivně zjevné a pokud je nedodržíš, nebude ti to fungovat. Těch věcí je jenom pár a můžu ti je vyjmenovat, pokud to potřebuješ.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 21. 10. 2019, 09:00:08
Žádná předběžná analýza kódu se v tomhle případě prostě nedělá.
Ehm, já žádnou předběžnou analýzu dělat nechtěl. Alespoň ne nutně.

V případě Aktorového systému jsem na tom podobně. Vzhledem k tomu, že to může být třeba přes vícero počítačů, tak když tam někdo zanese nějakou chybu, tak já nechci aby mi to všechno lehlo popelem. Zajímalo by mě to něco. Zajímalo by mě, jestli tomu můžu nějak zabránit. Ne absolutně, ne úplně. Ale alespoň trochu.
Tady mě zaujalo to slovo "všechno". Actor systém musí být udělaný tak, že jednotlivé actory jsou opravdu nezávislé. Takže nejhorší, co se ti může stát, je, že jeden actor (A) přestane fungovat. A případně ta jeho nefunkčnost způsobí nefunkčnost aktorů, které na něm závisí (B,C). V žádném případě by se ale nemělo stát, že přestane fungovat "všechno", zejména ne actor D, který s A ani B a C vůbec nekomunikuje.
No já si to představoval tak, že ti dva aktoři se zaciklí tak, že mi to shodí/extrémně vytíží ten runtime ve kterém to běží.
Ale to by se dalo řešit nějakým timeoutem, prioritizací, nebo tak něco.

P.S. Jak jsem tohle psal, tak mě napadlo, jestli náhodou se na tohle všechno neptáš proto, že zkoušíš napsat ten vlastní actorový systém (tj. tu vlastní infrastrukturu si píšeš sám). Pokud je to ten případ (nepoužíváš Erlang, Akka, ...), tak to určitě řekni, protože to by dost měnilo situaci. V tom vlastním systému je totiž potřeba dodržet pár věcí, které nejsou moc intuitivně zjevné a pokud je nedodržíš, nebude ti to fungovat. Těch věcí je jenom pár a můžu ti je vyjmenovat, pokud to potřebuješ.

Je to tak. Píšu si vlastní systém/runtime.

Napiš cokoliv ti přijde že by se mohlo hodit. Budu rád.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Mirek Prýmek 21. 10. 2019, 09:38:08
No já si to představoval tak, že ti dva aktoři se zaciklí tak, že mi to shodí/extrémně vytíží ten runtime ve kterém to běží.
Ale to by se dalo řešit nějakým timeoutem, prioritizací, nebo tak něco.
Já bych řekl, že taková situace se prostě neřeší, protože není účelné ji řešit. V praxi máš prostě systém něčím monitorovaný (Icinga apod.) a pokud se tam děje cokoli, co ti přijde divné (pod to patří i vyhulení CPU), tak se prostě koukneš, co se tam děje, to je celý, nic víc bych nehledal/neočekával.

Je to tak. Píšu si vlastní systém/runtime.

Napiš cokoliv ti přijde že by se mohlo hodit. Budu rád.
Ok, tak já ti napíšu ty zásadní body, jak komunikace funguje v Erlangu. V průběhu používání jsem zjistil, že každá featura má svoje opodstatnění, i když to tak třeba na první pohled nevypadá. Nechci říct, že tohle je jediná možnost implementace, ale tvrdím, že je to kombinace featur, která je dobře vymyšlená a v praxi velmi dobře otestovaná.

Must have:

1. Komunikace je striktně asynchronní (A pošle zprávu B, součástí zaslání není čekání na odpověď ani potvrzení). To je proto, že synchronní komunikace se dá pomocí asynchronní implementovat, ale naopak ne.

2. Každý proces (aktor) má mailbox. Zprávy se doručují striktně do mailboxu. Vždy přes něj projdou, nikdy se nekomunikuje "napřímo".

3. Zprávy je možné z mailboxu vybírat selektivně (ideální je na to pattern matching). To je potřeba nejenom kvůli prioritizaci, ale i kvůli tomu, abys mohl mít stavový protokol a zároveň víc než jednoho klienta.

4. V jazyce existuje nějaký mechanismus, kterým se dá čekat na konkrétní zprávu (opět pattern matching...). Ideálně samozřejmě ne stylem busy waiting, že jo...

5. Actory mají nezávislá vlákna provádění (je asi víc způsobů, jak tohle definovat, ale já bych řekl, že prostě zacyklení jednoho agenta nesmí způsobit vyhladovění jiných agentů).

Nice to have:

1. Neexistuje sdílená paměť mezi actory. (Pokud bys chtěl dodržet čistý actor model, tak by tohle patřilo mezi must have, já to tam nedávám, protože i se sdílenou pamětí by to šlo implementovat - akorát si tím způsobíš víc problémů než užitku...)

Hodí se, když "něco jako" sdílená paměť existuje, ale má to velmi striktní pravidla. Např. to nefunguje jako normální paměť, ale spíš jako databáze, u které se dá líp kontrolovat, kdo, kdy a jak tam přistupuje. V Erlangu se tohle jmenuje ETS. Snadno si vygooglíš spoustu článků o tom, jak to funguje. Nepoužívá se to často, ale existují případy, které by se bez toho implementovaly obtížně. Pro tvoje účely bych se na to zatím vyprdl a řešil to případně až narazíš na případ, kterej bez toho nepůjde dobře řešit.

2. Zprávy jsou čistě datové (tj. nesmí obsahovat ukazatele apod.) - tady opět platí to, co je v závorce u předchozího bodu.

3. Velice se hodí (ale není to striktně nutné) mít nějaký způsob supervize actorů. V Erlangu je na to několik primitiv a pracuje se s nima báječně. Klíčová slova: link, monitor, supervisor, supervisor tree.

4. V Erlangu existuje konvence "fail fast" nebo "let it crash", která říká, že nejlepší je velkou část chybových stavů řešit prostě pádem komponenty a jejím restartem supervisorem než nějakým složitým rozlišováním chyb a selektivním zotavením. Vypadá to divně, ale v praxi je to IMHO fakt hodně dobrý přístup. Řešíš totiž jenom jeden problém - supervizi. A jakmile ho vyřešíš dobře, máš víceméně kompletně vyřešenou obsluhu chyb :)
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Mirek Prýmek 21. 10. 2019, 09:41:14
5. Actory mají nezávislá vlákna provádění (je asi víc způsobů, jak tohle definovat, ale já bych řekl, že prostě zacyklení jednoho agenta nesmí způsobit vyhladovění jiných agentů).
K tomuhle bych ještě doplnil: nevím, jestli je to nutný, ale každopádně je imho nejlepší mít na agenta právě jedno vlákno. Velice to zjednoduší vývoj a usuzování nad kódem.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 21. 10. 2019, 18:09:46
2. Každý proces (aktor) má mailbox. Zprávy se doručují striktně do mailboxu. Vždy přes něj projdou, nikdy se nekomunikuje "napřímo".

Já to mám vymyšlený tak, že runtime vyzvedává zprávy a ty potom prochází “volá” aktor s tou zprávou.

Můžeš to okomentovat v čem je to řešení výhodnější/zajímavější.

3. Zprávy je možné z mailboxu vybírat selektivně (ideální je na to pattern matching). To je potřeba nejenom kvůli prioritizaci, ale i kvůli tomu, abys mohl mít stavový protokol a zároveň víc než jednoho klienta.
Jak to myslíš víc jak jednoho klienta?


1. Neexistuje sdílená paměť mezi actory. (Pokud bys chtěl dodržet čistý actor model, tak by tohle patřilo mezi must have, já to tam nedávám, protože i se sdílenou pamětí by to šlo implementovat - akorát si tím způsobíš víc problémů než užitku...)
Moje představa je, že se všechny data, úplně všechna posílají přes zprávy. Sdílená paměť by byl jakoze side-effect. Ale k tomu jsem se ještě nedopracoval.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Mirek Prýmek 21. 10. 2019, 20:10:43
Já to mám vymyšlený tak, že runtime vyzvedává zprávy a ty potom prochází “volá” aktor s tou zprávou.

Můžeš to okomentovat v čem je to řešení výhodnější/zajímavější.
Při téhle implementaci pravděpodobně narazíš, protože ti tam chybí právě ta možnost, aby si sám aktor určil, kterou zprávu chce zpracovat. Jestli teda dobře rozumím tomu, jak to myslíš.

Jak to myslíš víc jak jednoho klienta?
Actor poskytuje nějakou službu a ostatní actory tu službu využívají - v té chvíli se jim dá říkat "klient", protože to de facto není v tu chvíli nic jinýho než starej dobrej klient-server.

Pokud ten protokol je stavový (tj. jeden akt/session/... se skládá z víc než jedné zprávy a mezi zprávama je potřeba si pamatovat stav), tak se to může (ale nemusí) implementovat tak, že se vyřídí jeden "akt" (několik zpráv) v celku a až pak se jde na druhej. Jenže pokud je víc klientů, tak se ty zprávy můžou prolínat - a ty si potřebuješ vybrat tu, kterou teď zrovna chceš zpracovat.

Příklad:
Máš protokol:
A -- hi --> B
A <-- welcome -- B
A -- bye --> B
[konec]

Aktora B chceš z nějakýho důvodu napsat tak, aby tohle celý zpracoval naráz (nepřeskakoval mezi klienty). Zprávy mu ale můžou přijít pomíchaný:
1. A -- hi --> B
2. A <-- welcome -- B
3. C -- hi --> B
4. A -- bye --> B

- potřebuješ nutně možnost vybrat si selektivně zprávu 4. a teprve potom 3.

Možná se ti zdá, že tohle dělat nemusíš a dá se to obejít (třeba spawnutím spešl aktoru pro každou session). Stoprocentně ale narazíš na situaci, kdy to budeš potřebovat. Minimálně pro tu prioritizaci, která se (AFAIK) jinak než selektivním vybíráním zpráv řešit nedá.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Mirek Prýmek 21. 10. 2019, 20:13:41
Minimálně pro tu prioritizaci, která se (AFAIK) jinak než selektivním vybíráním zpráv řešit nedá.
No vlastně dá se řešit nějakou předřazenou "proxy", ale to je zbytečně krkolomný. Selektivní vybírání je prostě lepší.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Ondrej Nemecek 21. 10. 2019, 22:22:10
Jak to myslíš víc jak jednoho klienta?

Ten systém by mohl třeba umožňovat to, aby se - pokud jde např. o výpočetní úlohy - do systému registroval nějaký další aktor, který bude odebírat zprávy „výpočet hotov“ a bude z výsledku výpočtu dělat třeba grafy, statistiky nebo notifikace. Takový aktor by šel zaregistrovat ad-hoc, tj. by nebylo potřeba ostatní aktory pro tento případ upravovat, stačilo by napsat toho nového aktora a zaregistrovat ho, klidně za běhu systému. Nakonec by to mohlo vést na distribuovaný systém přes více počítačů.

IMHO by stačilo použít existující aktorový systém (akka (https://akka.io/) ...) - psát vlastní má smysl pro výukové potřeby nebo pro speciální případy (běh na speciálním hardware...).
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Mirek Prýmek 21. 10. 2019, 22:24:13
psát vlastní má smysl pro výukové potřeby
Což je myslím přesně to, o co BoneFlutovi jde - a je mu to ke cti :)
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 22. 10. 2019, 01:55:04
Já to mám vymyšlený tak, že runtime vyzvedává zprávy a ty potom prochází “volá” aktor s tou zprávou.

Můžeš to okomentovat v čem je to řešení výhodnější/zajímavější.
Při téhle implementaci pravděpodobně narazíš, protože ti tam chybí právě ta možnost, aby si sám aktor určil, kterou zprávu chce zpracovat. Jestli teda dobře rozumím tomu, jak to myslíš.

Jak to myslíš víc jak jednoho klienta?
Actor poskytuje nějakou službu a ostatní actory tu službu využívají - v té chvíli se jim dá říkat "klient", protože to de facto není v tu chvíli nic jinýho než starej dobrej klient-server.

Pokud ten protokol je stavový (tj. jeden akt/session/... se skládá z víc než jedné zprávy a mezi zprávama je potřeba si pamatovat stav), tak se to může (ale nemusí) implementovat tak, že se vyřídí jeden "akt" (několik zpráv) v celku a až pak se jde na druhej. Jenže pokud je víc klientů, tak se ty zprávy můžou prolínat - a ty si potřebuješ vybrat tu, kterou teď zrovna chceš zpracovat.

Příklad:
Máš protokol:
A -- hi --> B
A <-- welcome -- B
A -- bye --> B
[konec]

Aktora B chceš z nějakýho důvodu napsat tak, aby tohle celý zpracoval naráz (nepřeskakoval mezi klienty). Zprávy mu ale můžou přijít pomíchaný:
1. A -- hi --> B
2. A <-- welcome -- B
3. C -- hi --> B
4. A -- bye --> B

- potřebuješ nutně možnost vybrat si selektivně zprávu 4. a teprve potom 3.

Možná se ti zdá, že tohle dělat nemusíš a dá se to obejít (třeba spawnutím spešl aktoru pro každou session). Stoprocentně ale narazíš na situaci, kdy to budeš potřebovat. Minimálně pro tu prioritizaci, která se (AFAIK) jinak než selektivním vybíráním zpráv řešit nedá.

U tohoto se prosím ještě zastavme. Já bych to řešil právě tou session. Přijde mi to takové intuitivnější. Aktor A + Zpráva + Session komunikace (kterou dodá obsluha). Tedy to, zda je ta zpráva od aktora B, nebo C(, nebo dokonce B jiná session) řeší runtime, a nikoliv vlastní Aktor. Aktor je jen a pouze vlastní logika. Takto si to představuju. V čem bych mohl narazit?

Proč bych měl chtít, pokud jsem tě pochopil dobře, aby aktor nepřeskakoval mezi klienty?

Já bych si přestavoval, že ten aktor je do značné míry bezestavový. Respektive ten stav je uložen mimo, ve službách a v session. Ale samozřejmě si rád vyslechnu proč je to blbej nápad :-)
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 22. 10. 2019, 02:02:51
Jak to myslíš víc jak jednoho klienta?

Ten systém by mohl třeba umožňovat to, aby se - pokud jde např. o výpočetní úlohy - do systému registroval nějaký další aktor, který bude odebírat zprávy „výpočet hotov“ a bude z výsledku výpočtu dělat třeba grafy, statistiky nebo notifikace. Takový aktor by šel zaregistrovat ad-hoc, tj. by nebylo potřeba ostatní aktory pro tento případ upravovat, stačilo by napsat toho nového aktora a zaregistrovat ho, klidně za běhu systému. Nakonec by to mohlo vést na distribuovaný systém přes více počítačů.

Ano, tak nějak si to představuju. Zřejmě jsem jenom nepochopil jak to myslí s těmi klienty. Pochopitelně že ti aktoři jsou prostě v roli klient server.

To co popisuješ by ale vyžadovalo, aby ty data byly někde uschovány. Takže nějaký aktor "databázista/knihovník" který výsledky bude uchovávat. Nebo se k tomu poslednímu aktoru přihlásit jako subscriber, aby mi taky poslal výsledek. Ano, tyto vlastnosti a důsledky si uvědomuji.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Mirek Prýmek 22. 10. 2019, 08:53:44
U tohoto se prosím ještě zastavme. Já bych to řešil právě tou session. Přijde mi to takové intuitivnější. Aktor A + Zpráva + Session komunikace (kterou dodá obsluha). Tedy to, zda je ta zpráva od aktora B, nebo C(, nebo dokonce B jiná session) řeší runtime, a nikoliv vlastní Aktor. Aktor je jen a pouze vlastní logika. Takto si to představuju. V čem bych mohl narazit?

Proč bych měl chtít, pokud jsem tě pochopil dobře, aby aktor nepřeskakoval mezi klienty?

Já bych si přestavoval, že ten aktor je do značné míry bezestavový. Respektive ten stav je uložen mimo, ve službách a v session. Ale samozřejmě si rád vyslechnu proč je to blbej nápad :-)
Takže vlastně tvoje představa je spíš bližší HTTP než aktorovému systému ala CSP :) Jako proč ne? Klidně to tak udělat můžeš, ale pravděpodobně si tím na sebe uvalíš omezení, která ti pak neumožní dělat některé věci, které se v opravdovém aktorovém systému dělat dají, nebo budou zbytečně složité. Pravděpodobně se dostaneš k "něčemu podobnýmu RESTu" a hlavní otázka pak je, proč to vůbec dělat a nepoužít REST :)

Pokud bych měl říct konkrétněji, co mi přijde jako nevýhody takového řešení: pokud má runtime jakýmkoli způsobem manipulovat s komunikačními akty (např. je zhlukovat do těch sessions), tak:
1. musí té komunikaci rozumět (minimálně musí umět poznat začátek a konec)
2. buď teda budeš muset mít natvrdo jeden "metaprotokol" (např. zprávy "BEGIN" a "END" budou muset být součástí každé komunikace
3. nebo budeš muset nějak do runtimu nahrát popis protokolu
4. připravíš se o některé možnosti dynamického dispatche zpráv - u jednotlivých izolovaných zpráv můžeš třeba jednu konkrétní zprávu přehodit na jinýho aktora. Tady to nebudeš moct udělat, protože co by se pak dělo se session?

Už tohle je imho úplně zbytečný opruz, který tě bude stát jenom práci navíc, bude tě svazovat a nevidím žádný přínos, který by přinášel oproti klasice (neříkám, že neexistuje, jenom, že si ho teď neumím představit).

V klasickém aktorovém systému se můžeš ty, jako autor aktoru, rozhodnout, jestli v tu kterou chvíli komunikuje stylem "session" nebo stylem "ad hoc zpráva".  Prostě kód napíšeš tak nebo tak. Pokud budeš muset použít session, budeš mít úplně zbytečnou režii u komunikací, které session nijak nevyužijí (např. máš aktor, který čte stav tlačítka a když dojde ke změně stavu, pošle o tom zprávu jinému aktoru - to je bezestavová, jednozprávová komunikace, session tam k ničemu není).

Bez session:

A->B: switch=on
...
A->B: switch=off

S vynucenou session:

A->B: BEGIN
A->B: switch=on
A->B: END

+ režie toho, že někdo někde (úplně zbytečně) drží informace o té sešně.

Nevím, prostě se mi to intuitivně nezdá. Není to imho cesta správným směrem. Pokud chceš pochopit, na co jsou aktory dobré, drž se prostě CSP nebo toho, jak to má Erlang.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Ondrej Nemecek 22. 10. 2019, 09:24:40
Ten systém by mohl třeba umožňovat to, aby se - pokud jde např. o výpočetní úlohy - do systému registroval nějaký další aktor, který bude odebírat zprávy „výpočet hotov“ a bude z výsledku výpočtu dělat třeba grafy, statistiky nebo notifikace. Takový aktor by šel zaregistrovat ad-hoc, tj. by nebylo potřeba ostatní aktory pro tento případ upravovat, stačilo by napsat toho nového aktora a zaregistrovat ho, klidně za běhu systému. Nakonec by to mohlo vést na distribuovaný systém přes více počítačů.

Ano, tak nějak si to představuju. Zřejmě jsem jenom nepochopil jak to myslí s těmi klienty. Pochopitelně že ti aktoři jsou prostě v roli klient server.

To co popisuješ by ale vyžadovalo, aby ty data byly někde uschovány. Takže nějaký aktor "databázista/knihovník" který výsledky bude uchovávat. Nebo se k tomu poslednímu aktoru přihlásit jako subscriber, aby mi taky poslal výsledek. Ano, tyto vlastnosti a důsledky si uvědomuji.

Ano, buď si musí ti aktoři předávat kompletní data (pak budou aktoři bezstavové funkce cca ve smyslu funkcionálního programování) anebo musí mít nějaké sdílené úložiště (např. databázi), tedy sdílený stav.

Pokud by roli databáze plnil aktor, tak by šlo v principu o implementaci té první varianty, tj. kompletní předání dat (data by protékala message-busem toho systému). Asi bychom raději  chtěli, aby tím nevznikla explicitní závislost na „databázovém“ aktoru, takže bychom chtěli, aby o sobě aktoři nevěděli a pouze se registrovali k odběru událostí. Takže by pak komunikace mohla probíhala stylem:

Citace
A->systém: máte někdo data xy?
systém->A: tady má někdo data xy

Oprávnění by se řešilo předáním autorizačního tokenu při dotazu na data nebo při registraci k odběru události „tady má někdo data xy“. Záleží samozřejmě, zda by aktor věděl, kdo mu zprávu zasílá a zda by pak odpovídal zpětně tazateli, nebo zda by odpověď vkládal na message-bus, tj. emitoval zprávu „tady má někdo data xy“. Druhá varianta je lepší, pokud se vyřeší oprávnění a třídění zpráv kvůli výkonu (aby ten systém nelehnul, protože bude každý reagovat na každého).

Já bych to řešil právě tou session. Přijde mi to takové intuitivnější. Aktor A + Zpráva + Session komunikace (kterou dodá obsluha). Tedy to, zda je ta zpráva od aktora B, nebo C(, nebo dokonce B jiná session) řeší runtime, a nikoliv vlastní Aktor. Aktor je jen a pouze vlastní logika. Takto si to představuju. V čem bych mohl narazit?

Session znamená připojit stav k původně nestavovému protokolu. Zde vidím rozpor s tím, že jinde říkáš, že mají být aktoři nestavoví. Osobně bych se na session vykašlal, do aktorové koncepce IMHO moc nezapadá.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Mirek Prýmek 22. 10. 2019, 09:35:39
Ano, buď si musí ti aktoři předávat kompletní data (pak budou aktoři bezstavové funkce cca ve smyslu funkcionálního programování) anebo musí mít nějaké sdílené úložiště (např. databázi), tedy sdílený stav.
Drobná technická: v tomhle konkrétním případě žádné sdílené úložiště není potřeba, pokud aktor vykreslující grafy nebude nikdy požadovat historická data. Pokud bude jenom poslouchat přicházející data a z nich kreslit graf, tak potřebujeme držet jenom:
1. seznam aktorů, kteří data chtějí přijímat
2. buffer dat pro vykreslení grafu

První data si drží lokálně nějaký ten "distribuční" aktor, druhá data si drží lokálně grafovací aktor. Jsou potřeba jenom zprávy:
1. přihlašuji se k odběru
2. přibyl nový datapoint
3. odhlašuji se z odběru
a žádná sdílená data, žádná databáze.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Mirek Prýmek 22. 10. 2019, 09:41:13
Session znamená připojit stav k původně nestavovému protokolu. Zde vidím rozpor s tím, že jinde říkáš, že mají být aktoři nestavoví. Osobně bych se na session vykašlal, do aktorové koncepce IMHO moc nezapadá.
Myslím, že to BoneFlute řekl správně: pokud se všechna potřebná data drží v session, může být aktor nestavový.

Tenhle přístup se někdy používá v HTTP autorizaci. Jsou dvě cesty:
1. stavový aktor: klientům přiděluju IDčka a držím si tabulku "tohle ID má přístup do tehdy a tehdy"
2. nestavový aktor: do session uložím "přístup povolen do tehdy" a sám nemusím žádný stav držet (session ale musí být udělaná tak, aby s ní klient nemohl manipulovat - např. zašifrovaná serverem). Klient a server (aktor) si pak data session posílají tam a zpátky s každým requestem.

Název: Re:Uváznutí v Aktor systému
Přispěvatel: Ondrej Nemecek 22. 10. 2019, 14:32:44
Ano, buď si musí ti aktoři předávat kompletní data (pak budou aktoři bezstavové funkce cca ve smyslu funkcionálního programování) anebo musí mít nějaké sdílené úložiště (např. databázi), tedy sdílený stav.
Drobná technická: v tomhle konkrétním případě žádné sdílené úložiště není potřeba, pokud aktor vykreslující grafy nebude nikdy požadovat historická data.

Jasně, podobně i ten logovací aktor - taky jen zapíše a zapomene.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Ondrej Nemecek 22. 10. 2019, 14:44:56
Session znamená připojit stav k původně nestavovému protokolu. Zde vidím rozpor s tím, že jinde říkáš, že mají být aktoři nestavoví. Osobně bych se na session vykašlal, do aktorové koncepce IMHO moc nezapadá.
Myslím, že to BoneFlute řekl správně: pokud se všechna potřebná data drží v session, může být aktor nestavový.

A v případě aktorů by do té session přistupoval aktor nebo systém? Session může sloužit pro uložení ledasčeho, nejen autorizace. Ten storage na data bys řešil jak?
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Mirek Prýmek 22. 10. 2019, 15:49:52
A v případě aktorů by do té session přistupoval aktor nebo systém? Session může sloužit pro uložení ledasčeho, nejen autorizace. Ten storage na data bys řešil jak?
Já bych hlavně session v tomhle smyslu nepoužil. To byl BoneFlutuv napad.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Ondrej Nemecek 22. 10. 2019, 17:42:24
A v případě aktorů by do té session přistupoval aktor nebo systém? Session může sloužit pro uložení ledasčeho, nejen autorizace. Ten storage na data bys řešil jak?
Já bych hlavně session v tomhle smyslu nepoužil. To byl BoneFlutuv napad.

OK. I tak mě ale zajímá, jak bys řešil přístup k persistentnímu storage. A pak jestli bys nechal aktory komunikovat pomocí sběrnice, kde se mohou za běhu porůznu registrovat k odběru událostí jednotliví aktoři. Předpokládejme, že je cílem nějaký výpočetní cluster s probíhajícími výpočty, které na sobě porůznu závisí (nějaká simulace třeba).
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Mirek Prýmek 22. 10. 2019, 19:16:01
OK. I tak mě ale zajímá, jak bys řešil přístup k persistentnímu storage. A pak jestli bys nechal aktory komunikovat pomocí sběrnice, kde se mohou za běhu porůznu registrovat k odběru událostí jednotliví aktoři. Předpokládejme, že je cílem nějaký výpočetní cluster s probíhajícími výpočty, které na sobě porůznu závisí (nějaká simulace třeba).
Tezko rict, to je asi moc specificka otazka, ktera by zalezela na detailnich pozadavcich na ten system.

Obecne bych asi spis moc nepouzival slovo "sbernice", to do aktoroveho sveta imho moc nesedi. Pokud bych mel vypocetni cluster s nejakymi workery, kteri se hlasi o zadani vypoctu, tak bych mel asi nejaky "registr" aktor, kteremu by se worker ohlasil, ze chce praci a registr by workerum bud primo praci rozdeloval, nebo by jenom udrzoval jejich seznam a praci by rozdeloval zase jiny aktor. Zalezi hlavne na mnozstvi tech uloh - jestli by registr byl nebo nebyl uzky hrdlo...

Zavislosti se zase daji resit ruzne. Spawnovani novych actoru je typicky levne, takze casto se ruzne zavislosti daji resit treba tak, ze se spawne nekolik actoru a nekteri z nich proste cekaji na to, az se dokonci ulohy, na kterych jejich uloha zavisi. K tomuhle je ale dobry mit ten system "linku" - aby se dal cely ten "strom" actoru shodit naraz, pokud dojde k nejake chybe.

Persistentni storage je velky tema, silne implementacne zavisly. Jako rule of thumb bych se hlavne snazil dobre promyslet, jestli opravdu persistenci potrebuju. Mam zkusenost, ze dost casto se ukaze, ze vlastne vubec potreba neni.

Dam takovej pripad jedne veci, na ktere delam zrovna ted: jsou nejake streamy dat a nekdo nekdy v historii vymyslel, ze ty streamy budou oznacene nevyznamovymi IDcky (napr. "BFLM"). System funguje tak, ze prijdou data ze zarizeni, ktery ma ID treba "A", a v ramci toho zarizeni ma ten stream ID napr. "TEMP1" (je to teplota na prvnim cidlu). No a kdyz teda to dato prijde, tak se v databazi vyhleda mapovani (A, TEMP1) => BFLM a dal ten stream putuje pod timhle IDckem.

Zasadni otazka je, k cemu je vlastne to mapovani dobry. Co kdybych ten stream oznacil IDckem "A-TEMP1"? Prisel bych o neco? A pritom bych krasne odstranil perzistenci, databazi, pripadne i uplne stavovost...

To jenom takova drobna stupidni ilustrace...
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 23. 10. 2019, 02:06:35
A v případě aktorů by do té session přistupoval aktor nebo systém? Session může sloužit pro uložení ledasčeho, nejen autorizace. Ten storage na data bys řešil jak?
Já bych hlavně session v tomhle smyslu nepoužil. To byl BoneFlutuv napad.

Možná je zavádějící výraz Session. Co třeba Stav? Vlákno konverzace?

Ten Session/Stav byl myšlen, že mezi aktorem A a B vznikne komunikace, která pokračuje. Aktor si tam může uložit co chce, a pokud bude pokračovat ve stejném vláknu konverzace, tak to tam zase najde. Neslouží to k předání dat někomu jinému. Jakmile konverzaci ukončí, tak tato data zaniknou. Pokud začne novou konverzaci, tak tam také nejsou.

Představoval jsem si, že by bylo vhodnější, když by toto řešil systémově runtime, a nikoliv když by si to každý aktor dělal po svém. Ale promyslím si tvé výhrady.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Mirek Prýmek 23. 10. 2019, 11:20:13
Představoval jsem si, že by bylo vhodnější, když by toto řešil systémově runtime, a nikoliv když by si to každý aktor dělal po svém. Ale promyslím si tvé výhrady.
Proč myslíš, že je to vhodnější, a co očekáváš, že tím získáš? Actor sám má nejlepší informace o tom, v jaké fázi komunikace je, a taky vytváří ty data. Pokud použiješ tu session, tak oboje budeš muset předat někam jinam a při každém requestu si to zase brát zpátky. Není lepší si to prostě nechat u sebe? :)

Očekáváš, že když to budeš mít v runtimu na jednom místě, tak se ti to bude líp persistovat? Nebo?
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 23. 10. 2019, 13:51:39
Představoval jsem si, že by bylo vhodnější, když by toto řešil systémově runtime, a nikoliv když by si to každý aktor dělal po svém. Ale promyslím si tvé výhrady.
Proč myslíš, že je to vhodnější, a co očekáváš, že tím získáš? Actor sám má nejlepší informace o tom, v jaké fázi komunikace je, a taky vytváří ty data. Pokud použiješ tu session, tak oboje budeš muset předat někam jinam a při každém requestu si to zase brát zpátky. Není lepší si to prostě nechat u sebe? :)

Očekáváš, že když to budeš mít v runtimu na jednom místě, tak se ti to bude líp persistovat? Nebo?

Co to znamená "nechat u sebe"?

Očekávám, že získám
1. věci se budou dělat jedním způsobem
2. aktor bude bezstavovej, to znamená, že mohu zavolat toho samého aktora vícekrát
3. ano, můžu to líp persistovat, i třeba napříč stroji.

Hlavně mám ideu, že mám imutable aktora, který má závislosti na mutable službách.

Když si to bude ten aktor dělat sám, tak
1. bude muset mít stav - jak to budu řešit? Myšlenky mi stále sklouzávají do nějakého toho stavu, který budu muset někam dát.
2. Asi tedy nebudu moct zavolat aktor vícekrát.
3. Aktor si sám bude vyzobávat zprávy které chce. Bude si to sám nějak prioritizovat. Což se mi moc nechce mu tuto svobodu dopřát. Jaké to má výhody?
4. Aby si aktor uchoval stav, tak si zavolá jinej aktor?
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Mirek Prýmek 23. 10. 2019, 14:57:02
Co to znamená "nechat u sebe"?
Až budu mít chvilku času, pošlu ti ukázkovej kód v Elixiru. Jeden kód vydá za tisíc slov ;)

aktor bude bezstavovej [...] persistovat, i třeba napříč stroji.
Tímhle si vůbec nejsem jist. De facto (z hlediska implementace) totiž ten aktor bude stavovej. Akorát ten stav bude někde jinde. A to mi právě nepřijde elegantní. V Elixiru třeba když máš stavovýho aktora, tak když umře (z libovolnýho důvodu), tak s ním umře i celá jeho paměť - a tím i stav. Automaticky. Nemusíš to nijak řešit. Spíš naopak - pokud bys chtěl stav zachovat i po pádu, musíš to nějak pořešit, ale to obvykle právě nechceš).

Pokud ty budeš držet stav někde mimo toho aktora, jak zjistíš, že ten aktor umřel a stav máš zahodit? Budeš pořád dokola checkovat živost všech stavových aktorů? A dokonce i na vzdálených počítačích ("třeba napříč stroji")?

to znamená, že mohu zavolat toho samého aktora vícekrát
To můžeš i když si stav drží sám. Ukážu ti to na tom kódu později.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Mirek Prýmek 23. 10. 2019, 19:04:46
Tak pro tebe mám ty příklady :)

Úplně nejjednodušší actor, jenom abys viděl, jak se v Elixiru spawnují procesy a posílají zprávy:
Kód: [Vybrat]
$ curl -O https://gist.githubusercontent.com/mprymek/0308d05d79237211dd732436f7887cd6/raw/da55a5fc4c9878405cc0da1dcf15ea8cc4759a3d/01-simplest.exs

$ elixir 01-simplest.exs
[main] My PID: #PID<0.92.0>
[main] Agent a1 runs with #PID<0.97.0>
[SimplestActor] Got message from #PID<0.92.0>: 1
[SimplestActor] Got message from #PID<0.92.0>: 2

Bezestavový actor poskytující službu "přičti jedničku":
Kód: [Vybrat]
$ curl -O https://gist.githubusercontent.com/mprymek/0308d05d79237211dd732436f7887cd6/raw/da55a5fc4c9878405cc0da1dcf15ea8cc4759a3d/02-stateless.exs

$ elixir 02-stateless.exs
[main] My PID: #PID<0.92.0>
[main] Agent a1 runs with #PID<0.97.0>
[StatelessActor] Got message from #PID<0.92.0>: 1
[main] Got reply from actor a1: 2
[StatelessActor] Got message from #PID<0.92.0>: 2
[main] Got reply from actor a1: 3

No a do třetice různý variace na stavovýho actora...

Tohle je úplně chybná implementace, která nepočítá s více klienty a proto zhavaruje:
Kód: [Vybrat]
$ curl -O https://gist.githubusercontent.com/mprymek/0308d05d79237211dd732436f7887cd6/raw/da55a5fc4c9878405cc0da1dcf15ea8cc4759a3d/03a-statefull.exs

$ elixir 03a-statefull.exs
[main] My PID: #PID<0.92.0>
[main] Agent a1 runs with #PID<0.97.0>
[ChitChatActor2] Got message from #PID<0.92.0>: :hello
[main] Got reply from actor a1: :hello
[ChitChatActor2] Got message from #PID<0.92.0>: :bye
[ChitChatActor2] Session closed
[ChitChatActor2] Got message from #PID<0.92.0>: :hello
[main] Got reply from actor a1: :hello
[ccc #PID<0.98.0>] Starting
[ccc #PID<0.99.0>] Starting

18:48:20.866 [error] Process #PID<0.98.0> raised an exception
** (RuntimeError) Timeout!
    03a-statefull.exs:90: anonymous fn/1 in :elixir_compiler_0.__FILE__/1

18:48:20.870 [error] Process #PID<0.99.0> raised an exception
** (RuntimeError) Timeout!
    03a-statefull.exs:90: anonymous fn/1 in :elixir_compiler_0.__FILE__/1

Tahle je o trošičku lepší - vybírá zprávy selektivně, takže protokol zpracuje správně, ale pořád je chybná, protože neumí rozlišit sessions (nezajímá ji, od koho která zpráva je, takže klienti by klidně mohli posílat zprávy na střídačku a server by si toho nevšiml):
Kód: [Vybrat]
$ curl -O https://gist.githubusercontent.com/mprymek/0308d05d79237211dd732436f7887cd6/raw/da55a5fc4c9878405cc0da1dcf15ea8cc4759a3d/03b-statefull.exs

$ elixir 03b-statefull.exs
[main] Agent a1 runs with #PID<0.97.0>
[ccc #PID<0.98.0>] Starting
[ccc #PID<0.99.0>] Starting
[ChitChatActor2] Got message from #PID<0.98.0>: :hello
[ChitChatActor2] Got message from #PID<0.98.0>: :bye
[ChitChatActor2] Session closed
[ChitChatActor2] Got message from #PID<0.99.0>: :hello
[ccc #PID<0.98.0>] Everything OK
[ChitChatActor2] Got message from #PID<0.99.0>: :bye
[ChitChatActor2] Session closed
[ccc #PID<0.99.0>] Everything OK

No a tohle je už docela slušá implementace, na které můžeš vidět právě to, že si actor drží informace o sessions "u sebe" - a není to nijak zvlášť komplikovaný:
Kód: [Vybrat]
$ curl -O https://gist.githubusercontent.com/mprymek/0308d05d79237211dd732436f7887cd6/raw/f00a01adaafb1623923c9e3469040b9976ce2906/03c-statefull.exs

$ elixir 03c-statefull.exs
[main] Agent a1 runs with #PID<0.97.0>
[ccc #PID<0.98.0>] Starting
[ccc #PID<0.99.0>] Starting
[ChitChatActor3] Got message from #PID<0.98.0>: :hello
[ChitChatActor3] New session #PID<0.98.0>
[ChitChatActor3] Got message from #PID<0.99.0>: :hello
[ChitChatActor3] New session #PID<0.99.0>
[ChitChatActor3] Got message from #PID<0.98.0>: :bye
[ChitChatActor3] session #PID<0.98.0> closed
[ChitChatActor3] Got message from #PID<0.99.0>: :bye
[ChitChatActor3] session #PID<0.99.0> closed
[ccc #PID<0.98.0>] Everything OK
[ccc #PID<0.99.0>] Everything OK

No a tohle už je taková vcelku standardní implementace, která odbavuje každýho klienta pomocí vlastního procesu. Ve skutečné praxi by se to sice psalo trošku jinak, ale všechny základní principy tam jsou implementované dobře (pokud jsem se někde neupsal ;) ):
Kód: [Vybrat]
$ curl -O https://gist.githubusercontent.com/mprymek/0308d05d79237211dd732436f7887cd6/raw/da55a5fc4c9878405cc0da1dcf15ea8cc4759a3d/03d-statefull.exs

$ elixir 03d-statefull.exs
[main] Agent a1 runs with #PID<0.99.0>
[ccc #PID<0.100.0>] Starting
[ccc #PID<0.101.0>] Starting
[Proxy] Got message from #PID<0.100.0>: :hello
[Proxy] Creating handler Elixir.ChitChatHandler for session #PID<0.100.0>
[CCH #PID<0.100.0>] Starting
[CCH #PID<0.100.0>] got :hello from #PID<0.100.0>
[Proxy] handlers = %{#PID<0.100.0> => #PID<0.102.0>}
[Proxy] Got message from #PID<0.101.0>: :hello
[Proxy] Creating handler Elixir.ChitChatHandler for session #PID<0.101.0>
[Proxy] handlers = %{#PID<0.100.0> => #PID<0.102.0>, #PID<0.101.0> => #PID<0.103.0>}
[CCH #PID<0.101.0>] Starting
[CCH #PID<0.101.0>] got :hello from #PID<0.101.0>
[Proxy] Got message from #PID<0.100.0>: :bye
[CCH #PID<0.100.0>] got :bye from #PID<0.100.0>
[Proxy] Deleting handler for session #PID<0.100.0>
[Proxy] handlers = %{#PID<0.101.0> => #PID<0.103.0>}
[Proxy] Got message from #PID<0.101.0>: :bye
[CCH #PID<0.101.0>] got :bye from #PID<0.101.0>
[Proxy] Deleting handler for session #PID<0.101.0>
[Proxy] handlers = %{}
[ccc #PID<0.100.0>] Everything OK
[ccc #PID<0.101.0>] Everything OK
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Mirek Prýmek 06. 11. 2019, 19:57:38
BoneFlute, co je s tebou? Snad jsi se na to nevykaslal? To by byla skoda!
Název: Re:Uváznutí v Aktor systému
Přispěvatel: BoneFlute 07. 11. 2019, 00:27:48
Nevykašlal. Jen moc práce.

Mohl by si se prosím trochu rozkecat ohledně jedné věci, která mi není tak úplně jasná?

(Omlouvám se, ten Elixír je na mě zatím příliš velké sousto.)

...
Tohle je úplně chybná implementace, která nepočítá s více klienty a proto zhavaruje:
...
Tahle je o trošičku lepší - vybírá zprávy selektivně, takže protokol zpracuje správně, ale pořád je chybná, protože neumí rozlišit sessions (nezajímá ji, od koho která zpráva je, takže klienti by klidně mohli posílat zprávy na střídačku a server by si toho nevšiml):
...

Mě tak nějak furt nedochází, proč bych měl těm aktorům dávat volnost, když je pak tak snadné to evidentně napsat špatně. Snad je z mého úvodního příspěvku jasné, že mi jde o to, aby to pokud možno nešlo napsat špatně. Proč nevytvořit specializované třídy aktorů, kterým engine dodá co potřebují, a ony se soustředí na svou práci?

Já ti to věřím, že je to špatně. Ale rád bych pochopil proč, nějaký příklad, ukázku, a tak.
Název: Re:Uváznutí v Aktor systému
Přispěvatel: Mirek Prýmek 07. 11. 2019, 11:00:28
Mě tak nějak furt nedochází, proč bych měl těm aktorům dávat volnost, když je pak tak snadné to evidentně napsat špatně.
Protože jestli je to dobře nebo špatně záleží na tom, co implementuješ. V základu můžeš mít stavového a nestavového aktora a stavový a nestavový protokol. Souvisí to spolu, ale ne těsně, takže to je ortogonální => z tohodle pohledu můžeš mít celkem 4 možnosti toho, co chceš implementovat. A co je korektní v jedné nemusí být korektní v druhé.

Jinak ale ta tvoje myšlenka je správná, akorát se to řeší jinak: nějaká základní "šablona" aktoru je ve standardní knihovně a ty dodáš jenom callbacky implementující tu tvoji kýženou funkcionalitu. V erlang světě je taková nejčastější "šablona" http://erlang.org/doc/man/gen_server.html (implementuje stavováho aktora implementujícího potenciálně stavový protokol).

Takže máš vlastně pravdu, akorát se to nedělá na úrovni jazyka, kde by to bylo těžký a matoucí, ale na úrovni knihovny.