Files
simplex-chat/docs/rfcs/2024-06-17-agent-stats-persistence.md
spaced4ndy d951003191 core: servers summary api (#4319)
* core: servers summary api

* rework

* server known types

* set stats file path

* rename

* local simplexmq

* update

* rfc

* update

* update

* get servers

* compile summary

* remove sort

* rename

* rename, refactor

* refactor attempt

* refactor attempt 2

* refactor

* fix

* fix2

* remove space

* refactor xftp

* update

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
2024-06-25 09:51:55 +04:00

88 lines
4.6 KiB
Markdown

# Agent stats persistence
## Problem
State/state tracked in agent are lost on app restart, which makes it difficult to debug user bugs.
## Solution
Persist stats between sessions.
App terminal signals may vary per platform / be absent (?) -> persist stats periodically.
Stats would have `<userId, server>` key, so we don't want to store them in a plaintext file to not leak used servers locally -> persist in encrypted db.
There's couple of orthogonal design decision to be made:
- persist in chat or in agent db
- pros for chat:
- possibly less contention for db than agent
- pros for agent:
- no unnecessary back and forth, especially if agent starts accumulating from past sessions and has to be parameterized with past stats (see below)
- agent to start accumulating from past sessions stats, or keep past separately and only accumulate for current session from zeros
- pros for accumulating from past sessions:
- easier to maintain stats - e.g. user deletion has to remove keys, which is more convoluted if past stats are not stored in memory
- simpler UI - overall stats, no differentiation for past/current session (or less logic in backend preparing presentation data)
- pros for accumulating from zeros:
- simpler start logic - no need to restore stats from agent db / pass initial stats from chat db
- can differentiate between past sessions and current session stats in UI
### Option 1 - Persist in chat db, agent to track only current session
- Chat stores stats in such table:
```sql
CREATE TABLE agent_stats(
agent_stats_id INTEGER PRIMARY KEY, -- dummy id, there will only be one record
past_stats TEXT, -- accumulated from previous sessions
session_stats TEXT, -- current session
past_started_at TEXT NOT NULL DEFAULT(datetime('now')), -- starting point of tracking stats, reset on stats reset
session_started_at TEXT NOT NULL DEFAULT(datetime('now')), -- starting point of current session
session_updated_at TEXT NOT NULL DEFAULT(datetime('now')) -- last update of current session stats (periodic, frequent updates)
);
```
- Chat periodically calls getAgentServersStats api and updates `session_stats`.
- interval? should be short to not lose too much data, 5-30 seconds?
- On start `session_stats` are accumulated into `past_stats` and set to null.
- On user deletion, agent updates current session stats in memory (removes keys), chat has to do same for both stats fields in db.
- other cases where stats have to be manipulated in similar way?
### Option 2 - Persist in chat db, agent to accumulate stats from past sessions
- Table is only used for persistence of overall stats:
```sql
CREATE TABLE agent_stats(
agent_stats_id INTEGER PRIMARY KEY, -- dummy id, there will only be one record
agent_stats TEXT, -- overall stats - past and session
started_tracking_at TEXT NOT NULL DEFAULT(datetime('now')), -- starting point of tracking stats, reset on stats reset
updated_at TEXT NOT NULL DEFAULT(datetime('now'))
);
```
- Chat to parameterize creation of agent client with initial stats.
### Option 3 - Persist in agent db, agent to differentiate past stats and session stats
- Table in agent db similar to option 1.
- Agent is responsible for periodic updates in session, as well as accumulating into "past" and resetting session stats on start.
- Agent only communicates stats to chat on request.
- On user deletion agent is fully responsible for maintaining both in-memory session stats, and updating db records.
### Option 4 - Persist in agent db, agent to accumulate stats from past sessions
- Table in agent db similar to option 2.
- On start agent restores initial stats into memory by itself.
- Since all stats are in memory, on user deletion it's enough to update in memory without updating db.
- there is a race possible where agent crashes after updating stats (removing user keys) in memory before database stats have been overwritten by a periodic update, so it may be better to immediately overwrite and not wait for periodic update.
- still at least there's at least no additional logic to update past stats.
### Other considerations
Why is it important to timely remove user keys from past stats?
- stats not being saved for past users:
- important both privacy-wise and to not cause confusion when showing "All" stats (e.g. user summing up across users stats would have smaller total than total stats).
- to avoid accidentally mixing up with newer users.
- though we do have an AUTOINCREMENT user_id in agent so probably it wouldn't be a problem.
- on the other hand maybe we don't want to "forget" stats on user deletion so that stats would reflect networking more accurately?