jam231 / sia

Stock market server (part of stock market simulation system).
1 stars 0 forks source link

Sposób implementacji obsługi zleceń #8

Closed kaiks closed 11 years ago

kaiks commented 11 years ago

Zacząłem coś grzebać w SQLu i chcę zrobić (w wariancie optymistycznym dziś) obsługę zleceń poprzez funkcje i wyzwalacze po stronie bazy.

Według mnie jest to ładne, ale niesie to ze sobą parę kwestii. Po pierwszej, jak wydajne będzie takie rozwiązanie (przetestujemy to tak czy inaczej a wypadałoby coś mieć do pokazania na środę (bo w środę są zajęcia czwartkowe).

Po drugie: aby zacząć kleić te transakcje, chcę żeby część rzeczy się działa na wyzwalaczach. To sprawia, że np. wykonanie funkcji "wyślij_zlecenie_kupna" nie otrzymuje informacji zwrotnej dotyczącej tego jakie transakcje się wykonały (chociaż jakby się uprzeć to tak też się da, ale raczej powinniśmy zwrócić ID zlecenia, niż listę wykonanych zleceń). W Postgresie jest coś takiego, jak kanały powiadomień: http://www.postgresql.org/docs/9.0/static/sql-notify.html . Czy takie powiadamianie o tym co się stało nie jest jakąś wielką zbrodnią?

Jest jeszcze trzecia kwestia: jeśli chcemy mieć kontrolę sesji (tj. symulacje rozpoczynania sesji giełdowej), musimy po stronie bazy trzymać informacje o obecnym stanie sesji. Rozwiązanie, które mi się w tej chwili nasuwa, to do każdego zasobu w tabeli zasób przypisać powinniśmy na przykład wartość boolowską "w_stanie_sesji" lub coś takiego. To by pozwoliło też na zawieszanie akcji pojedynczych firm (tak też się dzieje na giełdzie). Jestem otwarty na inne sposoby kontroli sesji giełdowej.

jam231 commented 11 years ago

Ja również uważam, że takie rozwiązanie jest ładne. Myślę, że będzie bardziej wydajne niż nasz jednowątkowy serwer, ale tak jak napisałeś to się jeszcze okaże.

Myślę, że wyzwalacz odpowiedzialny za realizacje transakcje, gdy już uda mu się zrealizować jakieś zlecenie może wysyłać szereg wiadomości do serwera przez specjalny kanał komunikacyjny (vide link który podałeś).

W Qt to się robi jakoś tak (chyba):

db.driver()->subscribeToNotification("channelfoo"); QObject::connect((QObject)db.driver(), SIGNAL(notification(const QString&)), (QObject_)&myObject, SLOT(myNotifyHandler(const QString&)));

Co do sesji, to wydaję mi się, że wystarczyłoby trzymać jeden byt, który by trzymał stan giełdy. Widzi mi się jakaś zmienna globalna (fuu...). Ja tu widzę jednak dość spory problem związany z wyzwalaczami właśnie. Rozumiem, ze np. akcja referencyjna zmiany stanu sesji byłoby "uśpienie" wyzwalaczy ?

kaiks commented 11 years ago

Nie wiem czy opłaca się usypiać kanał. Bardziej chodzi mi o jakiegoś IFa w funkcjach SQLowych przy wstawianiu zlecenia: jeśli handel akcją, na której zlecenie zostało wstawione, jest wstrzymany, to nie próbuj realizować go w parze z żadnym innym, tylko po prostu wstaw do tablicy zlecenia. Natomiast jeśli zmienimy stan na aktywny, wtedy należy zacząć parować po kolei zlecenia ze sobą.

marimarek commented 11 years ago

Nie wiem, czy mówienie o tych sesjach na etapie na którym jesteśmy jest podstawne i czy naprawdę musimy mieć te sesje? Ale ok jak mają być to nie lepiej by było to robić poprzez powiadomienie wszystkich o przerwie w sesji przestawienie wszystkiego w serwerze co się może zmienić podczas takiej przerwy i powiadomienie wszystkich o wznowieniu sesji. Przecież chyba nie będziemy robić przerwy w sesji przez jakiś dłuższy okres przez który nie będzie się nic dziać, bo niby po co? I mi się cały czas wydaje, że ten podział na sesje nic nie zmieni. Mam cały czas wrażenie, że dążycie do zrobienia jak najbardziej realistycznego serwera giełdy, a nie symulacji, a to 2 różne rzeczy.

kaiks commented 11 years ago

Już o konieczności sesji mówiłem wiele razy. Lipiński na konsultacjach powiedział, że to ważne zjawisko. Czas między sesjami będzie krótki fizycznie (tj. w świecie rzeczywistym), ale te przerwy (symulujące osobne dni) są konieczne bo bez nich nie będzie pewnych zjawisk na giełdzie. Zobacz sobie choćby tu, na trzydniowy wykres WIG20: http://stooq.pl/q/?s=wig20&c=3d&t=l&a=lg&b=0 . Skoki znaczące odbywają się często między dniami.

Druga sprawa, że po stronie aplikacji to jedno, a po stronie bazy danych to drugie. Musisz rozróżniać między akcjami które w bazie danych dzieją się przy włożeniu zlecenia w czasie sesji i przy włożeniu zlecenia bez czasu sesji (lub: w czasie zamrożenia instrumentu finansowego, o czym nie wspomniałeś też), a przynajmniej ja to tak chcę zrealizować. Wtedy musisz w bazie trzymać informacje na temat tego których z firm akcjami możesz handlować.

Oczywiście jeśli masz inny pomysł i/lub wolisz to sam zaimplementować do końca niedzieli to nie będę się upierał.

jam231 commented 11 years ago

@kaiks Chodziło mi o ogólny mechanizm zmiany zachowania, a nie o konkretny sposób realizacji ;-) Nie sądzę byśmy musieli debatować nad takimi szczegółami technicznymi - pozostawiłbym je realizatorowi.

@marimarek Nie bardzo rozumiem "... to nie lepiej by było to robić poprzez powiadomienie wszystkich o przerwie w sesji przestawienie wszystkiego w serwerze co się może zmienić podczas takiej przerwy ..." Mógłbyś podać nieco precyzyjniej co miałoby się przestawiać i jak ?

Ja sądzę, że wpakowanie reguł dotyczących zachowań podczas sesji jak i poza nią do bazy jest właściwym rozwiązaniem. Serwer powinien tylko pytać bazy, czy jest w trakcie sesji (żeby informować o tym użytkowników - bardzo drobna funkcjonalność, a dość przydatna biorę na siebie jej implementacje jakby co) oraz ustanawiania\wyłączania sesji.

marimarek commented 11 years ago

Dobra spoko, zapomniałem, że w czasie "zamrożenia" też mogą przychodzić zlecenia.