Já teda žiju ve světě, kde je tohle default, nemusí se pro to dělat žádné speciální extra podpora...
Ano, matematici zkoumají i různé bizardní světy, ale nevím v tom, že by v takovém někdo žil
Celou věc diktuje logika. Viz dále.
Pokud je problém s použitou technologií...
On je problém
nejen s použitou technologií. Ale hlavně s logikou. Viz dále.
Obecně je podle mne zrovna u IB řešení vícenásobného přístupu poměrně snadné, ...
Ani smykem. Respektive, udělat to tak, aby to "nějak" spatlaně fungovalo opravdu jednoduché je. Ale v bankovnictví je třeba preciznosti a jasnosti. A udělat to pořádně je obtížné až nemožné. Viz dále.
Pokud je problém jenom v tom, že server drží stav klientského GUI, je zbytečné bránit uživateli používat dvě různé session – z pohledu serveru by to byly dvě různé instance s odlišným stavem (pokud by stav byl skutečně svázán se session a ne přímo s uživatelským účtem).
To typický naivní, začátečnická představa. A fatálně chybná. Začnu nejprve "klasickým" případem, kdy přistupujete v jedné session. Trik je v tom, uvědomit si, že tady není
jeden stav, ale
dva(*) stavy. Jeden stav databáze serveru a druhý stav UI (= to co má uživatel zobrazeno, v případě webu HTML elementy). Tyto stavy je třeba synchronizovat a je to práce UI aplikace - když pošle mutaci na backend, musí si zajistit občerstvení stavu tak, aby její stav reflektoval změny na serveru.
V případě, kdy pracujete ve dvou session paralelně, tak nastává problém. V session 1 něco změním, ale aplikace v session 2 to neví, tedy neaktualizuje svůj stav ze serveru a stavy se rozejdou. Do určité míry by to šlo řešit nějakým systémem push aktualizací, třeba GraphQL na tohle má subscriptions, nicméně to není automatické, je potřeba ty závislosti naprogramovat a tak se to používá spíš jen ve specializovaných případech. Pak se dá používat nějaký polling, ale ten zase bere prostředky navíc a stejně není stoprocentní, když uživatel "stihne kliknout" než se data zaktualizují.
Tedy v okamžiku, kdy se rozjedou stavy na klientovi a na serveru, máme problém. Někdo tu zmiňoval nákupní košík, ukáži to tedy na něm. Mějme košík, kde mám u položky akce "odstranit kus", "přidat kus", "nastavit počet kusů" a "odstranit položku". Dále je možno zaplatit.
Vezměme si teď následující scénáře:
A) Uživatel má v košíku 5ks, v jedné session položku odstraní, ve druhé klikne na "přidat kus". Tady je několik možností, kde každá dává smysl:
1) vyhodit chybu, že položka už neexistuje (detekce neplatné operace)
2) přidat položku a mít tam jeden kus (operaci definujeme jako "přidej 1 ks tohoto výrobku do košíku ať se děje co se děje")
3) přidat položku a mít tam celkem 6 kusů (podle toho, co uživatel viděl, než klikl)
Problém je v tom, že každý uživatel bude mít jiný, silný, názor na to, která cesta je správná a když se bude aplikace chovat jinak, bude nadávat. Úplně klasický případ tu předvedl Jenda:
(OMG! si v Tescu otevřete do tabů 10 výrobků a seznamů, že si je prohlídnete a naházíte do košíku, a ono si to obsah košíku navzájem přepíše!)
Třeba zmiňované Tesco se chová podle logiky v bodě 3 (košík viděl uživatel prázdný a přidal jednu položku => má tam tu jednu položku). Nicméně Jenda by chtěl, aby se to chovalo podle logiky v bodě 2. Jenže to by pak zase jiný uživatel přišel s tím, jak to, že se mu v košíku objevují položky, které tam neviděl... Žádné řešení není správné.
S ostatními operacemi budou vznikat další kolize, ale ty vám nechám k analýze za domácí úkol
Proberu ještě jednu věc související s placením:
B) Řekněme, že mám možnost placení uloženou kartou. Tedy uživatel dojde na stránku shrnutí objednávky, potvrdí ji a ta se zaplatí. Ale co když mezi zobrazením stránky a jejím odkliknutím přidá do košíku ještě další položku? Pak odklikne nějakou objednávku (a cenu) a zaplatí jinou! A tady už jde do tuhého, tady jde o peníze, takže uživatelé si na vás hezky smlsnou. (Podobná věc se stala právě zakladateli tohoto vlákna - potvrdil něco jiného, než co měl na obrazovce.)
Tenhle případ by se samozřejmě dal řešit - například tak, že při odkliknutí potvrzení pošle klient na server i objednávku
a pokud nesouhlasí s tam uloženým stavem, vyhodí se chyba, kterou klient nějak ošetří, například aktualizuje stav a napíše informaci, že se změnil a je třeba potvrdit znovu. A pak tedy ještě musí řešit, že třeba uživatel něco odebral, tím se dostal pod minimum zvoleného druhu dopravy a je třeba zvolit nový druh dopravy, tedy jít ve flow o stránku / dvě zpět - samé složitosti.
Už je to hrozné dlouhé, takže abych to shrnul: Je možné udělat aplikace, které umožňují paralelní práci, aby "nějak" fungovaly. Pokud se v nich převážně čte a na konzistenci obsahu až tak nezáleží, tak to docela funguje bez většího množství práce (třeba zrovna Root). Jenže pak jsou aplikace, kde narážíte na docela nepříjemné problémy, které musíte ošetřovat. Jen se podívejte, na co jsme narazili u pitomého nákupního košíku.
Pokud to chcete ošetřit pořádně, tak musíte:
1) Identifikovat jednotlivé scénáře (Kolik jste jich identifikovali jen u toho jednoduchého košíku? A jste si jistí, že jste identifikovali opravdu všechny? Můžete to nějak verifikovat?)
2) Definovat, jak se mají řešit (ale vždycky bude někdo nadávat, že to máte blbě)
3) Naprogramovat
4) Otestovat
5) V nových verzích aplikace myslet, jestli tím nemůžete způsobit nějakou další kolizi, ošetřovat je plus na tu kopu už existujících scénářů dělat regresní testy
Tedy u složitější aplikace pěkná kopa práce navíc, často pro podporu minoritních use-cases a uživatelé vám budou stejně nadávat. Proto složitější aplikace jako třeba IB práci ve víc paralelních session typicky nepodporují.
*) Kdybych měl být precizní, tak těch kopií stavů je ještě víc, v různých cache, frontend mívá svůj uložený datový model, který pak reflektuje v UI, ale synchronizace těchto stavů problém není, ty základní a z našeho pohledu zásadní jsou dva.