pub/sub event reflection
Nemrég találkoztam egy érdekes problémával, gondoltam megosztom veletek is. Az egész data binding-hoz kapcsolódik, illetve js-hez, de általánosítható bármilyen nyelvre.
Az alap probléma gyakorlatilag egy általános data binding megoldás keresése volt. Elég szépen le lehet írni a data binding-ot, mert körülbelül arról van szó, hogy adat forrásokat kell szinkronba hozni. Az egyik a model, a másik a view, de lehet tetszőleges számú model és view is. Pl backbone esetében hozzácsapnak egy model-t egy view-hoz és szevasz. Ha általánosan akarjuk leírni a dolgot, akkor n:m reláció esetében a legegyszerűbb, ha létrehozunk egy relationship típust, amiben letároljuk, hogy mi áll mivel kapcsolatban. Szóval arra gondoltam, hogy csinálni kell egy Hub osztályt, ami majd továbbítja a többi adatforrásnak a change event-eket.
A gond csak ott van ezzel a megközelítéssel, hogy az adatforrás, ami kiváltja az eseményt szintén fel van iratkozva erre a Hub-ra, mint esemény figyelő. Így könnyen előfordulhat az, hogy elkezd a rendszer oszcillálni attól, hogy az adatforrás és a hub között vagy két adatforrás között oda-vissza verődnek az események. Egy change egy adatforráson kivált egy eseményt, ezt publikálja a Hub-on, ami visszaküldi ugyanazt az eseményt, ami szintén kivált egy change-t, ami kivált egy új eseményt, és így tovább... Mit gondoltok mi erre az általános megoldás?
■ Az alap probléma gyakorlatilag egy általános data binding megoldás keresése volt. Elég szépen le lehet írni a data binding-ot, mert körülbelül arról van szó, hogy adat forrásokat kell szinkronba hozni. Az egyik a model, a másik a view, de lehet tetszőleges számú model és view is. Pl backbone esetében hozzácsapnak egy model-t egy view-hoz és szevasz. Ha általánosan akarjuk leírni a dolgot, akkor n:m reláció esetében a legegyszerűbb, ha létrehozunk egy relationship típust, amiben letároljuk, hogy mi áll mivel kapcsolatban. Szóval arra gondoltam, hogy csinálni kell egy Hub osztályt, ami majd továbbítja a többi adatforrásnak a change event-eket.
A gond csak ott van ezzel a megközelítéssel, hogy az adatforrás, ami kiváltja az eseményt szintén fel van iratkozva erre a Hub-ra, mint esemény figyelő. Így könnyen előfordulhat az, hogy elkezd a rendszer oszcillálni attól, hogy az adatforrás és a hub között vagy két adatforrás között oda-vissza verődnek az események. Egy change egy adatforráson kivált egy eseményt, ezt publikálja a Hub-on, ami visszaküldi ugyanazt az eseményt, ami szintén kivált egy change-t, ami kivált egy új eseményt, és így tovább... Mit gondoltok mi erre az általános megoldás?
Ránézésre ez az egész
Gondoltam arra, hogy egy irányúsítani kellene az események folyását, tehát mondjuk van egy központi model, és minden adatforrás arról frissíti saját magát. Ez a megoldás biztosan nem működik, több okból sem, az egyik, hogy nem lehet bonyolultabb hub hierarchiát építeni, mert mindig a legfelső szinthez kellene hozzányúlni mindennek, a másik az, hogy a view esetében nincs választási lehetőség, mindenképp az input mező változásait kell, hogy figyeljük, és az input mező az egyedüli dolog, amihez hozzáfér a felhasználó, a memóriához közvetlenül nem.
Az adatforrás tudja, hogy mi
Ez csak szinkron kódnál oldja
Miért nem tageled meg az
Nope, saját maga által
Tudsz mondani egy példát,
Megoldódott már amúgy? Elég csöndes lett ez a téma.
https://github.com/szjani/pre
Itt van pl egy olyan helyzet, amikor a domain object kivált egy domain event-et a konstruktorban, aztán saját maga kezeli le a created metódusban. DDD-ben ez elég tipikusnak tűnik, bár nem ástam bele magam kimondottan, de láttam már máshol is ugyanezt. Úgy nézem, hogy valószínűleg az indokolja, hogy event sourcing esetében szükség lehet az aggregate újbóli felépítésére a tárolt event-ek alapján.
A hub-os dolog nem sokban különbözik. Ott is ugyanúgy felteszi egy bus-ra az event-eket a data source, amiket ő is figyel, csak annyi a különbség, hogy ott a saját maga által kiváltott event-eket nem ő kezeli le... Hmm ami érdekes, hogy ugyanaz a megoldás működhet, mint amit szjani alkalmazott. Szóval hogy mondjuk egy set() metódus csak egy event-et vált ki, de nem csinál semmit a property-kkel, illetve az event elkapása megváltoztatja a property-ket, de nem vált ki újabb event-et... Ez bizonyos típusú rendszereknél működhet, de sajnos ez sem általános megoldás, mert szűkíti a lehetőségek körét, egy hub-nál nem jutnának tovább az event-ek, hacsak nem több hub-ot kapcsolnánk össze azok továbbítására...
Egyébként megoldódott:
http://stackoverflow.com/questions/23968758/how-to-avoid-event-reflection-by-pub-sub
http://programmers.stackexchange.com/questions/241599/how-to-avoid-oscillation-by-async-event-based-systems
de ha van észrevételed, nyugodtan jelezd.
Én arra gondoltam, hogy a legáltalánosabb megoldás minden kívülről indult eseményhez egy-egy context-et hozzácsatolni, és ezt a context-et végigvinni új események kiváltásakor is. Erre nyilván ki kell alakítani egy context továbbító rendszert. Így ha egy konkrét context id-vel ellátott event valamikor már kezelve volt 1-1 handler által, akkor az nem kerül újra kezelésre. Ezt megvalósítani nem egyszerű, az event-et kiváltó osztályba muszáj beleírni hasonló módon, mint pl a backbone-nál, ahol options-t fogad el egy csomó metódus második paraméterként, amiben át lehet adni egy silent-et, ha meg akarjuk szakítani az oszcillációt... Ez mondjuk egy gyenge manuális kezelése a problémának. Ott az váltja ki az oszcillációt, hogy a view-ot és a model-t szinkronban kell tartani, és ezek kölcsönösen figyelik egymás eseményeit, illetve módosuláskor mindegyik eseményt vált ki, amit a másik elkap...
Ok, így már azt hiszem jobban
Ez a könnyebbik része, a
egy event küldésének a
Kifejtenéd?
Parancssor
array_shift()
), és lefuttatja a hozzá tartozó parancsot. Ha a parancs feldolgozása közben új események váltódnak ki, a hozzájuk tartozó parancsok a parancssor elejére kerülnek.FIFO = First In, First Out.
És ez hogy oldja meg az
a nehezebbik, ha egy event
Hogyan?
Azt hiszem, elbeszélünk