-
Notifications
You must be signed in to change notification settings - Fork 3
Implement notification counts #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
c459bfb
c868cfa
66f95c3
699ca8f
9063fc8
7653f1e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| Add notification counting for events | ||
|
|
||
| - spec states "The updated notification count from a new event MUST appear in the same /sync response as the event itself." | ||
| - store as rooms.users.notificationVersions (userid, roomid, version) -> types.Notifications{notifs, highlights, ...} | ||
| - store types.Notifications as msgpack with single letter keys | ||
| - for every event send we must (SendLocalEvents, SendFederatedEvents): | ||
| - get local users in the room | ||
| - get all their push rules (stub these for now), before any write txn | ||
| - inside the txn for each event, eval each users rules, map eventsToUserNotifications[id.EventID]types.Notifications{} | ||
| - pass to txnStoreEvents, we apply notificationVersions (userid, roomid, eventVersion) -> types.Notifications{} | ||
| - version is the event version (so can get back to the eventid) | ||
| - on sync, just | ||
| - range notificationVersions (userid, roomid) => sum counts | ||
| - on receipt just | ||
| - clearrange up to (userid, roomid, eventVersionFromReceipt) | ||
|
|
||
| Explore the codebase and come up with a plan to implement the above changes. | ||
|
|
||
| ... implemented, second prompt: | ||
|
|
||
| Now we need to implement an EventNotificationIterator to compact notificationVersions: | ||
|
|
||
| - compact notificationVersions by aggregating old -> new (userid, roomid, version) | ||
| - just iter events constantly compact | ||
| - so should just be merging 2 -> 1 constantly, unless falls behind | ||
| - note: in future this worker will also actually turn each (unaggregated) notification into an actual notification for each of the users configured push targets | ||
|
|
||
| Explore the codebase and come up with a plan to implement the above changes. | ||
|
|
||
| ... implemented, third prompt | ||
|
|
||
| Let's extend notification counts to handle threads. We need to: | ||
|
|
||
| - add ThreadID to types.Notifications (already done) | ||
| - in eventsend.go, we: | ||
| - move the notification generation into a new read txn, just before each write txn | ||
| - include threadID in generated notifications, this is: | ||
| - "" if event has no relation | ||
| - $event_id of thread root (found by walking thread relations of m.thread type until no more) | ||
| - we need two ways to sum notifications: | ||
| - the current one is fine for non-threading clients | ||
| - new sum by threadID version | ||
| - update sync | ||
| - add SyncOption to enable threaded notification counts | ||
| - when set, sum by threadID and update sync response accordingly | ||
|
|
||
| Explore the codebase and come up with a plan to implement the above changes. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| Add push rules to the accounts database | ||
|
|
||
| - store Matrix push rules in a new directory in the accounts database, keys: | ||
| - userPushRules (userID, groupName, kind, ruleID) -> partial mautrix.PushRule | ||
| - kind is one of: override, underride, sender, room, content | ||
| - userPushVersions (userID) -> versionstamp of last written rule | ||
| - new methods: | ||
| - AccountsDatabase.GetRulesForUser | ||
| - AccountsDatabase.GetRuleForUser | ||
| - AccountsDatabase.PutRuleForUser | ||
| - AccountsDatabase.DeleteRuleForUser | ||
| - sync must return all the users push rules if the userPushVersion > the sync token as m.push_rules account data event | ||
|
|
||
| Explore the codebase and come up with a plan to implement the above changes. | ||
|
|
||
| ... implemented, second prompt: | ||
|
|
||
| Now we need to evaluate the push rules during event sending. | ||
|
|
||
| - add databases.SendLocalEvents which calls rooms.SendLocalEvents | ||
| - modify rooms.SendLocalEvents to take userid -> pushrules map | ||
| - databases.SendLocalEvents fetches local users in room -> makes the map | ||
| - rooms.SendLocalEvents then uses push rules for evaluation | ||
| - same for databases.SendFederatedEvents -> rooms.SendFederatedEvents | ||
|
|
||
| Explore the codebase and come up with a plan to implement. | ||
|
|
||
| ... implemented, second prompt: | ||
|
|
||
| Now we need to implement Matrix pushers APIs: | ||
|
|
||
| - store Matrix pushers (mautrix pushgateway.Pusher) for users in UsersDirectory | ||
| - userPushers subspace (userID, pushKey) -> pushgateway.Pusher | ||
| - methods: | ||
| - AccountsDatabase.GetPushersForUser | ||
| - AccountsDatabase.SetPusherForUser | ||
|
|
||
| Explore the codebase with a few agents (databases, routes) and come up with a plan to implement. | ||
|
|
||
| ... implemented, second prompt: | ||
|
|
||
| Finally, now that we've implemented the various push components, let's actually send some push notifications! | ||
|
|
||
| - we're going to base this on the CompactNotificationIterator, which is currently disabled | ||
| - to prevent the notifications keyspace growing indefinitely (UsersDirectory.notificationVersions), we add a configurable limit to the number of notifications per user/room to keep, this worker will handle deleting the oldest N to maintain the limit (this means read receipt accuracy over the most recent X events per room) | ||
| - let's call it PushNotificationIterator, it now has two responsibilities: | ||
| - as events come in, send pushes as required | ||
| - remove old notification count keys | ||
| - to implement this, for every event that comes in: | ||
| - fetch all the local users in the room | ||
| - for each user, fetch push notification keys up to (including) the event version | ||
| - if notification was generated for this event (ie userid/roomid/eventversion notification exists), fetch users pushers and send it to each in parallel | ||
| - delete oldest push notifications > the configurable limit | ||
|
|
||
| Explore the codebase with a few agents (databases, routes) and come up with a plan to implement. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,4 +5,5 @@ ed25519-* | |
| *.pem | ||
| babbleserv | ||
| external/ | ||
| .claude/ | ||
| .claude/settings.local.json | ||
| *.frpc | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -21,15 +21,22 @@ Ingesting federated events is a good example of this - all the network fetching | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## Module Layout | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Babbleserv is roughly divided in three: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - databases talk to FoundationDB, no access to network/federation, implements Matrix spec on top of the databases (event auth, state res) using FDB transactions | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - routes implement the client/federation Matrix APIs, pre-fetch anything before passing to relevant database call | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - workers handle asynchronous tasks after database changes (federation outgoing, profile updates, presence, push notifications) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ### `internal/databases/*/` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - each represents a FDB cluster containing a logical group of sub-databases | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - top level database transactions called by routes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - call through to the domain specific directories nested modules | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - each database lives under a key prefix | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #### `internal/databases/*/*/` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - individual database "directories" (FDB thing) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - individual database "directories" (key prefix) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - group together common key prefix operations (ie events, users) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+24
to
40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hyphenate compound adjectives in module layout bullets. Minor grammar polish per static analysis. ✏️ Suggested edit-- top level database transactions called by routes
-- call through to the domain specific directories nested modules
+- top-level database transactions called by routes
+- call through to the domain-specific directories nested modules📝 Committable suggestion
Suggested change
🧰 Tools🪛 LanguageTool[uncategorized] ~33-~33: If this is a compound adjective that modifies the following noun, use a hyphen. (EN_COMPOUND_ADJECTIVE_INTERNAL) [grammar] ~34-~34: Use a hyphen to join words. (QB_NEW_EN_HYPHEN) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - not exported/available outside of database | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: "evens" should be "events".
📝 Committable suggestion
🧰 Tools
🪛 LanguageTool
[grammar] ~47-~47: Ensure spelling is correct
Context: ...ons
API will not returnm.annotationevens unless therel_type` is explicitly spe...(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🤖 Prompt for AI Agents