210 lines
5.8 KiB
Markdown
210 lines
5.8 KiB
Markdown
# Bot Microservices: Hasura + Fastify
|
|
|
|
Ten dokument jest kontraktem architektonicznym dla nowych serwisow bota.
|
|
|
|
## Zasady
|
|
|
|
1. Zawsze najpierw powstaje dokument kontraktu serwisu, potem implementacja.
|
|
2. Hasura jest jedynym source of truth dla danych i stanu wspoldzielonego.
|
|
3. Fastify jest shell-em mikroserwisu: HTTP, health, readiness, trigger, observability.
|
|
4. Logika domenowa nie siedzi w Fastify handlerach. Jest w czystych modulach `processing`.
|
|
5. Serwisy maja byc male i wyspecjalizowane. Kazdy liczy jeden skladnik decyzji albo jedna spojna klase skladnikow.
|
|
6. Serwis nie staje sie drugim systemem stanu. Jesli wynik ma byc wspoldzielony, zapisujemy go do Hasury albo wystawiamy przez endpoint.
|
|
7. Podzial na mikroserwisy robimy po granicach domenowych i kontraktach danych, nie po pomocniczych funkcjach.
|
|
|
|
## Model runtime
|
|
|
|
Kazdy serwis ma ten sam ogolny przeplyw:
|
|
|
|
`Hasura GraphQL -> input adapter -> processing -> output adapter -> Fastify endpoint`
|
|
|
|
Warstwy:
|
|
|
|
- `inputs/hasura`
|
|
- zapytania GraphQL
|
|
- mapowanie rekordow Hasury do lokalnych struktur
|
|
- `processing`
|
|
- czyste funkcje liczace cechy, score, klasyfikacje, gating
|
|
- `outputs/hasura`
|
|
- zapis wyniku, eventu, state snapshotu
|
|
- `transport/http`
|
|
- Fastify
|
|
- endpointy health, ready, latest result, admin trigger
|
|
- `orchestration`
|
|
- petla, harmonogram, retry, timeouty, kolejnosc krokow
|
|
|
|
## Rola Fastify
|
|
|
|
Fastify nie jest miejscem na model matematyczny.
|
|
|
|
Fastify odpowiada za:
|
|
|
|
- `GET /healthz`
|
|
- `GET /readyz`
|
|
- `GET /result/latest`
|
|
- `GET /result/:id`
|
|
- `POST /run`
|
|
- start i stop serwisu
|
|
- logowanie i metryki
|
|
|
|
Fastify moze odpalac processing synchronicznie albo przez worker/job, ale sama logika ma pozostac poza transportem.
|
|
|
|
## Rola Hasury
|
|
|
|
Hasura jest source of truth dla:
|
|
|
|
- konfiguracji bota
|
|
- snapshotow i tabel pochodnych
|
|
- wynikow i eventow serwisow
|
|
- historii potrzebnej do debugowania i replay
|
|
|
|
Mikroserwis:
|
|
|
|
- czyta z Hasury
|
|
- liczy wynik
|
|
- opcjonalnie zapisuje wynik do Hasury
|
|
- opcjonalnie wystawia ten wynik przez HTTP
|
|
|
|
Nie trzymamy osobnego "prawdziwego" stanu tylko w RAM mikroserwisu.
|
|
|
|
## Granica mikroserwisu
|
|
|
|
Dobry mikroserwis:
|
|
|
|
- ma jeden glowny kontrakt wejsciowy
|
|
- ma jeden glowny wynik
|
|
- ma jasny owner danych
|
|
- da sie niezaleznie uruchomic i przetestowac
|
|
|
|
Zly mikroserwis:
|
|
|
|
- laczy wiele niespojnych modeli w jednym procesie
|
|
- ma wiele roznych odpowiedzialnosci
|
|
- staje sie nowym centrum stanu
|
|
|
|
## Proponowany podzial
|
|
|
|
Minimalne serwisy obliczeniowe:
|
|
|
|
1. `bot-config-service`
|
|
- czyta konfiguracje z Hasury
|
|
- wystawia znormalizowany kontrakt configu
|
|
|
|
2. `market-snapshot-service`
|
|
- czyta candles i derived DLOB z Hasury
|
|
- wystawia ujednolicony snapshot rynku
|
|
|
|
3. `momentum-service`
|
|
- liczy `mom_3s`, `mom_10s`, `mom_30s`, `vol_30s`
|
|
|
|
4. `microstructure-service`
|
|
- liczy spread, depth, imbalance, slippage
|
|
|
|
5. `observer-service`
|
|
- scala wyniki serwisow skladowych
|
|
- ocenia gate'y
|
|
- liczy finalny wynik obserwacji
|
|
- zapisuje event i aktualny state
|
|
|
|
Nie trzeba wdrazac ich wszystkich od razu jako osobne procesy. Najpierw dokumentujemy kontrakty, potem mozemy zaczac od modularnego monolitu i dopiero potem wycinac osobne procesy.
|
|
|
|
## Czy bloczek modelu zawsze jest osobnym serwisem
|
|
|
|
Nie.
|
|
|
|
Bloczki z modelu matematycznego w `bot1.tex` sa optymalna jednostka dokumentacji i analizy.
|
|
Nie kazdy bloczek jest jednak optymalna jednostka deploymentu.
|
|
|
|
Zasada:
|
|
|
|
- `bot1.tex` opisuje bloczki matematyczne
|
|
- kontrakt serwisu grupuje bloczki, ktore maja wspolne wejscie i wspolny wynik runtime
|
|
- osobny proces wdrazamy dopiero wtedy, gdy taka granica ma sens operacyjny
|
|
|
|
To oznacza, ze:
|
|
|
|
- `momentum + volatility` to dobry jeden serwis, bo oba licza sie z candles
|
|
- `spread + depth + imbalance + slippage` to dobry jeden serwis, bo wszystkie licza sie z DLOB
|
|
- `gating + scoring + final observer result` lepiej trzymac razem na poczatku niz rozbijac zbyt drobno
|
|
- `mom_3s`, `mom_10s`, `mom_30s` jako trzy osobne procesy nie maja sensu
|
|
|
|
## Rekomendowane granice dla strategii v1
|
|
|
|
Najbardziej sensowny podzial runtime dla obecnej strategii:
|
|
|
|
1. `market-snapshot-service`
|
|
- jeden odczyt z Hasury
|
|
- candles i derived DLOB
|
|
|
|
2. `momentum-service`
|
|
- wszystko liczone tylko z candles
|
|
- `mom_3s`, `mom_10s`, `mom_30s`, `vol_30s`
|
|
|
|
3. `microstructure-service`
|
|
- wszystko liczone tylko z derived DLOB
|
|
- spread, depth, imbalance, slippage
|
|
|
|
4. `observer-service`
|
|
- pobiera wyniki serwisow skladowych albo liczy je lokalnie
|
|
- ocenia gate'y
|
|
- liczy score i finalny wynik
|
|
- zapisuje eventy i state
|
|
|
|
To jest lepsze niz rozbijanie strategii 1:1 po kazdym wzorze, bo:
|
|
|
|
- zmniejsza liczbe round-tripow do Hasury
|
|
- zmniejsza narzut operacyjny
|
|
- zachowuje czytelne granice domenowe
|
|
- nadal pozwala skalowac glowne klasy obliczen niezaleznie
|
|
|
|
## Zasada "small services"
|
|
|
|
Mniejsze serwisy sa preferowane, bo:
|
|
|
|
- latwiej je skalowac niezaleznie
|
|
- latwiej je testowac
|
|
- latwiej je debugowac
|
|
- latwiej wymienic jeden model bez ruszania reszty
|
|
|
|
Ale "mniejsze" nie znaczy "po jednej funkcji na proces".
|
|
|
|
Jednostka podzialu to:
|
|
|
|
- spojny kontrakt danych
|
|
- spojna odpowiedzialnosc obliczeniowa
|
|
- sensowny deployment boundary
|
|
|
|
## CPU i deployment
|
|
|
|
Mamy duzy zapas CPU, wiec wolno nam preferowac prostsze, bardziej izolowane procesy zamiast upychania wszystkiego do jednego serwisu.
|
|
|
|
To nie zmienia zasad:
|
|
|
|
- nie duplikowac source of truth
|
|
- nie mieszac transportu z logika
|
|
- nie rozbijac na mikroserwisy bez kontraktu
|
|
|
|
## Kontrakt dla nowego serwisu
|
|
|
|
Kazdy nowy serwis powinien miec dokument opisujacy:
|
|
|
|
- nazwe i cel
|
|
- wejscie z Hasury
|
|
- wynik obliczen
|
|
- zapis wyjscia do Hasury
|
|
- endpointy Fastify
|
|
- model bledow
|
|
- SLA petli albo triggera
|
|
|
|
## Stan biezacy
|
|
|
|
`services/bot-observer` zostal juz przesuniety w dobra strone:
|
|
|
|
- Fastify jako shell
|
|
- Hasura client osobno
|
|
- snapshot loader osobno
|
|
- model decyzji osobno
|
|
- state/event write osobno
|
|
|
|
Kolejny krok to dalsze cięcie po kontraktach, nie po plikach.
|