-
Notifications
You must be signed in to change notification settings - Fork 2
/
TODOs.txt
115 lines (97 loc) · 4.68 KB
/
TODOs.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
=== TODOs ===
P1
* consolidate API /matches, /matches/{matchid} - visibility
* consolidate MatchDTO API /matches -- OpenAPI is too complex returning both condensed and full MatchDTO
P2
* socket.io -- later could rework onto using selective namespaces instead of rooms
* optimize: db changestream notification used in waiting on matches.controller / use playerscache in game.controller
* consolidate filter/starteddate GMT/UTC incliding io rooms and filters
* API usage measurement: usage { id, total_accesscount, day_accesscount, lastaccess }
* env/option to selectively start/serve only FE or BE
P3
* jest component test and mock and test to check basic movements and state transitions e.g. simple draw, busted draw, ...
* use tsoa routes to generate route
* Create a proper frontend React/View/Svelte w jamstack
SOMEDAY / improve
* typeORM/typedorm/mongoose based ORM, instead of manual hydration
* move to GCP Cloud Functions / jamstack - separate API, frontend and listener IO
* https://www.npmjs.com/package/ts-json-object
CONSIDER
* hide @Hidden admin endpoint(s) from swagger - e.g. terminate
* do not need to store state for _all_ events associated with a move?
* icons: ⚓💣🎁🔱🗝️🐙🗺️🧜🏼♀️🗡️🔮 || backup 🔫💣,🧰🎁,🔱⛏,🧚🧜🏼♀️
* discriminator on classes for serialization/deserialization
ARCH:
* separate jamstack -> FE / even serverless SSR React | all FE
* separate serverless -> serverless-http | all API
* separate socket.io -> some eventing? / Pub/Sub | phase 2socket.io mech
* explore netlify/AWS serverless
* serverless => close connections
SYSTEM DESIGN:
* mongodb connection pool is the shortcoming ~57 parallel connections
theoretical should be M0 500 parallel connections
Your M2 cluster has three nodes with a 500 connection limit per node. Atlas reserves 10 connections per node. If you set your
read preference to secondary, Atlas can read from the two secondary nodes for a combined 980 connection limit.
Atlas sets the limits for concurrent incoming connections based on the cluster tier and class. Atlas connection limits apply per node. For
sharded clusters, Atlas connection limits apply per mongos router. The number of mongos routers is equal to the number of replica set nodes across all shards.
* mongodb compression - https://vicuesoft.com/blog/titles/MongoDB_compression_options/
=== BUGs KNOWN ===
* n/a
================================================================
// app
// .route('/matches/statistics')
// /matches/statistics?from=12/1/2022&to=12/31/2022&tags=alma,korte&status=finished|active
// implicit filter by player or admin
// Csaba: tournament stats: tag+(?date)=>[winnerid,scores]
// calendar picker: filterset(tags,date+-range,(user)) => day/count [{}]
===
PERFORMANCE
db size is significant and connection to mongodb server creates high load
- change streams progress each small change to N nodes to keep the frontend updated - though this is a nice-to-have
- database storage could be compressed
- database communication tested with snappy/zlib
- storage of all statuses in all events in all moves might not be necessary - could consider dropping the event-status
===
DB-DESIGN v2.0 (fields to be persisted):
[Match]
_id
playerIds[]
startedAt
creationParams: [MatchCreationParams]
{
playerIds[]
tags[]
drawPile[]
discardPile[]
banks[][]
randomSeed
createdByPlayerId
}
(moves stored separately as no need to update/persist in the same doc as we do not need to read back everything)
(btw: when hydration happens need to load back move header fields + lastevent)
//currentplayeridx() -> ( last_move_preloaded.currentplayeridx() + (last_move_preloaded.turnended() ? +1 : 0) ) % numplayers // increment if move ended turn
[move]
_id
matchId
userAction?: UserAction;
clientIP?: string;
at: Date;
sequenceId: integer //1..n, increments with every move/user interaction
sequenceTurnId: integer //1..m, increments with every turn (turnstarted->turnended)
sequenceInTurnId: integer | null; //1..k, increments with every move, restarts at any new turn: turn+inturn 1.1, 1.2, 2.1, 2.2, 2.3, ...
stateAtTurnStart: state // state cached at turn start, for delta calculation
//turnended(): if lastevent contains "turnended" --> new turn to be started
//state(): -> events[-1].state
//currentplayeridx() -> events[-1].currentplayeridx
events: Array<MatchEvent> = []; // ref 1-N matchevent [MatchEvent]
{
eventType?: MatchEventType;
state?: State; // ref 1-1: [State] {
currentPlayerIndex: integer; // 0/1
banks: Array<Bank>;
drawPile: DrawCardPile;
discardPile: DiscardCardPile;
playArea: PlayArea;
pendingEffect?: CardEffect; //-- e.g. Hook, Map (not Kraken)
+ specific fields for events
}