Room State Management
Planning and design of the room state management "feature."
- The bot must keep track of rooms it is in, and what users are in each room.
- The bot should keep track of information about a room: the room ID, the room name, etc.
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. 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 ID0xff
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 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.
- We may not get information for all participants, if their join events are old. So instead, sync all user info when bot joins a room for the first time.
- 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.
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.
Create src/models.rs
.
RoomInfo must store at least:
- Room ID
- 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.
Architecture Changes
Implementation of a new resync command, and common code used by both the room member changed event and execution of this command.
Implementation
Most functionality is in a new database object Rooms
. It contains all functions for storing information about rooms and users.
The code is being reorganized to support a new command called resync.
A new "business logic" layer needs to be created that can do things like update room info. This is because it might be called from a command, event handler, or even bot startup.