From 832ec8cb44c4e2477c11d25e2493029c5671faad Mon Sep 17 00:00:00 2001 From: projectmoon Date: Mon, 9 Nov 2020 21:40:11 +0000 Subject: [PATCH] Update 'Feature: Room State Management' --- Feature%3A-Room-State-Management.md | 53 ++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/Feature%3A-Room-State-Management.md b/Feature%3A-Room-State-Management.md index 47bcaf6..da870a9 100644 --- a/Feature%3A-Room-State-Management.md +++ b/Feature%3A-Room-State-Management.md @@ -6,30 +6,31 @@ Planning and design of the room state management "feature." * The bot should keep track of information about a room: the room ID, the room name, etc. -## Database Changes - -New DB object `Rooms`. Keep track of users and the rooms they are in, both by username to a list of room IDs, and a room ID to list of usernames. It will also keep track of actual room information and other useful stuff. - -Trees: -* username -> list of room ids, for easy implementation of private conversation command execution. -* room id -> list of users -* room id -> RoomInfo -* processed events: room id `0xff` event id -> timestamp (basically hash set of processed event IDs) - ## Matrix Event Processing -This is a core problem to solve before the rest, because all information needed to implement this feature comes from room member events. - -One of the core aspects of Matrix is that everything is a series of events. A room with messages is basically a decentralized database of event information. When logging in, or joining a room, it is possible for the bot to receive events it's already gotten in the past (notably this happens when re-joining a room that the bot was kicked from). Since our handling of Matrix events is not idempotent, and we cannot guarantee we will get all events from the server to properly replay everything, we must not process events we've already processed in the past. +This is a core problem to solve before the rest, because all information needed to implement this feature comes from room member events. When logging in, or rejoining a room, it is possible for the bot to receive events it's already gotten in the past. Since our handling of Matrix events is not idempotent, and we cannot guarantee we will get all events from the server to properly replay everything, we must not process events we've already processed in the past. The simplest way to do this is to keep track of processed events in the database. * A `Tree` that uses room ID `0xff` event ID as the key and the local processed timestamp as the value gives us an efficient way to stop event duplication. -* This applies to every single event handler. Check if the event is in the database, and if not, record it and allow processing. This should be able to be accomplished atomically with Sled. +* This applies to every single event handler that has a room and event ID attached to the event. Check if the event is in the database, and if not, record it and allow processing. This should be able to be accomplished atomically with Sled. +* We also need to track event IDs by room ID `0xff` timestamp, with event ID as the value. This allows easy cleanup of old event IDs using Sled's range APIs. +### Database Changes + +New trees specific to the event processing: + +* For reads (checking if we have seen an event): room id `0xff` event id -> timestamp. +* For cleanup/metadata tracking (quickly delete old events); room id `0xff` timestamp -> HashSet of event IDs. ## Keeping Track of Users and the Rooms They Are In +### Database Changes + +New trees specific to keeping track of users: +* For user-focused reads: username -> HashSet of room ids. +* For room-focused reads: room id -> list of users + ### Bot Changes Listen to Matrix event for when users enter and leave rooms. This is easily accomplished with the `on_room_member` event. When the bot joins a room for the first time, member events are fired for every member in the room. @@ -38,8 +39,6 @@ Listen to Matrix event for when users enter and leave rooms. This is easily acco * If the bot is kicked or banned, it does not get events for users leaving a room. Instead, it will get a member event of leaving the room for itself. In that circumstance, it should delete all user information in the database for the room. * Otherwise, we can simply processed user join/leave events as they come in, and update the data for that specific user. -RoomInfo struct is created/updated when the bot joins a room. - ### Architcture Changes A new `RoomInfo` struct must be created, and possibly a whole new layer of the application. This layer doesn't exist yet, because we've been dealing only with strings and integers so far. @@ -48,4 +47,24 @@ Create `src/models.rs`. RoomInfo must store at least: * Room ID -* Room name \ No newline at end of file +* Room name + +## Keeping Track of Room Info + +The bot needs to keep track of rooms as a specific entity, if only for metadata purposes at first. New struct `RoomInfo` holds room name, room ID, and maybe some other stuff. + +### Database Changes + +This data schema is actually very simple. New trees: + +* room ID -> room information (serialized RoomInfo instance). + +### Bot Changes + +Need to utilize `on_room_member` event for this: + +* When the bot joins a room for the first time, in addition to recording all users, it should also record information about the room itself. + +## Implementation + +Most functionality is in a new database object `Rooms`. Keep track of users and the rooms they are in, both by username to a list of room IDs, and a room ID to list of usernames. It will also keep track of actual room information and other useful stuff.