Eventualna konzistencia CQRS aplikacii a UI

hknmtt

Eventualna konzistencia CQRS aplikacii a UI
« kdy: 05. 01. 2023, 17:26:53 »
V aplikacii ktora funguje na principe eventualnej konzistencie, teda vykonana akcia sa neprejavi okamzite na reade, sa v praxi stane ze napriklad uzivatel vytvori clanok a je presmerovany na zoznam svojich clankov, kde vsak tento novy clanok este nebude. Musi teda obnovit stranku, eventualne viac krat, nez sa zmena prejavi.

V CQRS aplikacii ktoru robim je toto dost problem pretoze v mnohych pripadoch, ako vyssie uvedeny, je to velmi neprijemne user experience(UX). Na webe su rozne postupy rieseni, ako je posielat v odpovedi informacie ktore sa vyrenderuju a daju uzivatelovi pocit ze zmena sa prejavila, lenze tento postup je realne nepouzitelny, pretoze by to okrem tvrdej previazanosti na UI taktiez skomplikovalo front-end a akykolvek vyvoj do buducna.

Potom je tu long polling, teda uzivatel vykona akciu ale namiesto presmerovania, z uvedeneho pripadu, na zoznam clankov bude cakat kym sa zmena propaguje a az potom sa presmeruje. Toto zase predstavuje problem s cakanim a navyse ak read server nie je iba jeden, tak sa moze stat ze uzivatel dostane OK od jedneho read serveru, ktory zmenu uz zaznamena, ale po presmerovani uzivatel nacita obsah z ineho read serveru ktory ju este nema.

Dalsia moznost je presmerovat na zoznam clankov s url argumentom ktory na pozadi spusti long polling a automaticky doplni nove data do vypisu. Co je ok az na to ze to nefunguje ak uzivatel pouzije napriklad filter na vypise, kedy server nemoze vediet ci dany clanok ma byt sucastou vysledkov, alebo nie.

Verzia tohto by mohla byt ze akcia vrati id zmeny a po presmerovani na zoznam clankov sa na pozadi spusti dopyt na read server, ktory odosle toto id a ked server toto id lokalne zaznamena, cize zmenu uz ma, tak sa automaticky reloadne obsah stranky(nie plny refresh, len hlavne data na stranke). Cize aj ked ma uzivatel aktivny filter, len sa to reloadne javascriptom a rebuildne(co dnes v pripade reaktivnych JS frameworkov nie je problem).

V kazom pripade, vo vysledku tu je stale neprijemne UX.

Verim ze je tu plno ludi co CQRS riesilo v prevadzke a maju skusenosti z hladiska UI a UX tak by ma zaujimali vase postupy z praxe - co sa vam osvedcilo a td.


Re:Eventualna konzistencia CQRS aplikacii a UI
« Odpověď #1 kdy: 05. 01. 2023, 20:11:04 »
někde bude muset počkat až ti doputuje tvůj domain event s uloženým článkem. Dobře UX funguje třeba ponechání dat na clientu pro vytvoření náhledu nového článku s vizuálním označením, že se teprve ukládá, jakmile se uloží, překreslíš ho, ty to nazýváš jako long polling.

CQRS je v mnoha případech nadužívaný, vede k vyšší komplexitě, lagů při zobrazování (to řešíš) a duplikování kódu (viz tady třeba zobrazení draft z jiných dat na klientu).

Je pro tebe CQRS nutnost? Zatím jsem se v českém prostředí nesetkal s projektem, který by byl tak velký, aby pro něj byla CQRS nutnost.

Re:Eventualna konzistencia CQRS aplikacii a UI
« Odpověď #2 kdy: 06. 01. 2023, 10:46:40 »
Řešení je spousta, záleží na vašem technologickém stacku. Třeba u SPA aplikací je běžné, že má aplikace v prohlížeči cache, kde má seznam článků. Při odeslání článku se článek přidá i do té lokální cache, třeba i s příznakem, že jde o provizorní záznam. Při přechodu na stránku se seznamem článků se pak použijí údaje z cache a na pozadí se dotáhnou aktualizovaná data. I s tím můžete pracovat a ten provizorní záznam v cache ponechat do té doby, dokud nepřijde jeho aktualizace ze serveru.

Pokud byste v prohlížeči neměl takovouhle cache, můžete seznam článků vracet rovnou v odpovědi na přidání článku – a do toho seznamu můžete opět uměle přidat ten nový článek.

To, jestli uživatel má nebo nemá vidět nový článek ve výpisu, když nesplňuje podmínky filtru, je věc UX a je to nezávislé na technologii – smysl dávají obě možnosti, záleží na konkrétním způsobu použití.

Já bych to začal řešit nejdřív na straně UX. To, že trvá tak dlouho, než se nový záznam objeví v DB pro čtení, se děje často? Pokud ano, neměl by uživatel spíš vidět, že se záznam teprve ukládá? Tj. že by měl někde na stránce notifikaci nebo seznam běžících úloh a tam by viděl, že se článek teprve ukládá? Protože jedna věc je, že se dá článek podvrhnout do následujícího výpisu, ale pokud to ukládání může trvat déle, může uživatel přejít někam dál, kde už mu to podvrhnout nedokážete. Nebo dokonce může stihnout informovat o tom jiného uživatele, který ten článek neuvidí. Pokud něco takového hrozí, dává smysl spíš to uživateli přiznat, že ukládání trvá déle a ještě probíhá.