Phase 8: push and notifications
Implements PLAN.md Phase 8. internal/pushrules is the rule language: the spec's default ruleset, all six condition kinds, glob and word-boundary matching, intentional mentions switching off the legacy body rules, and rule ordering as Synapse has it. internal/pushserver keeps the rules, pushers and notifications and talks to push gateways. Push rules are the m.push_rules account data, written only by the push server; reads keep the user's own rules and the enabled/actions of each default and take the rest from the current defaults, so new default rules reach every user without a migration. PUT account_data/m.push_rules is refused with 405. The push server listens on the roomserver's emit stage and evaluates each event on its own worker for every local member and an invite's target. Notifications and per-room unread counts are stored in migration 0010; counts are a seventh sync token stream, so /sync reports unread_notifications and picks up count changes made after the event or by a receipt from another device. m.read and m.read.private receipts clear the counts; leaving a room clears it. Pushers (http kind only) push through a bounded sender pool with retries, honour event_id_only, drop push keys the gateway rejects, and go away with their device. GET /notifications pages the history. New config section push: enabled, include_content, gateway_timeout, notification_retention. Account data writes now wake the user's blocked syncs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
74f7bc8805
commit
b507753172
47 files changed
+5136
-50
No files matched your search
@@ -28,8 +28,9 @@
|
||||
//
|
||||
// Phase 4 of PLAN.md, with device lists from Phase 7: the keyserver writes
|
||||
// the device list stream, and this package works out which of its changes
|
||||
// concern whom (devicelists.go). What it does not do yet is notification
|
||||
// counts, which need push rules (Phase 8); docs/sync.md names that gap.
|
||||
// concern whom (devicelists.go). Notification counts, from Phase 8, are
|
||||
// the push server's: it writes them and their stream, and a sync reports
|
||||
// them per joined room (notifications.go).
|
||||
package syncapi
|
||||
|
||||
import (
|
||||
@@ -82,12 +83,24 @@ type Keys interface {
|
||||
DeviceListChanges(ctx context.Context, userIDs []string, from, to int64) ([]storage.DeviceListChange, error)
|
||||
}
|
||||
|
||||
// Push is the part of the push server a sync reads: the push rules it
|
||||
// reports as account data, the unread counts of each room, and which
|
||||
// rooms' counts moved. It is also told about read receipts, which are what
|
||||
// clear the counts. *pushserver.API satisfies it.
|
||||
type Push interface {
|
||||
Document(ctx context.Context, localpart, userID string) ([]byte, error)
|
||||
NotificationCounts(ctx context.Context, userID string, roomIDs []string) (map[string]storage.NotificationCounts, error)
|
||||
NotificationCountChanges(ctx context.Context, userID string, from, to int64) ([]string, error)
|
||||
ReceiptSet(ctx context.Context, userID, roomID, receiptType, threadID, eventID string)
|
||||
}
|
||||
|
||||
// API is the syncapi component.
|
||||
type API struct {
|
||||
serverName string
|
||||
rooms *roomserver.API
|
||||
accounts Accounts
|
||||
keys Keys
|
||||
push Push
|
||||
store storage.SyncStore
|
||||
notifier *Notifier
|
||||
typing *typingTracker
|
||||
@@ -126,6 +139,10 @@ type Options struct {
|
||||
// both device lists empty.
|
||||
Keys Keys
|
||||
|
||||
// Push is the push server. Nil leaves the notification counts out of
|
||||
// a sync, and m.push_rules is then whatever account data holds.
|
||||
Push Push
|
||||
|
||||
// Store is the sync half of storage.
|
||||
Store storage.SyncStore
|
||||
|
||||
@@ -206,6 +223,7 @@ func New(opts Options) (*API, error) {
|
||||
rooms: opts.Rooms,
|
||||
accounts: opts.Accounts,
|
||||
keys: opts.Keys,
|
||||
push: opts.Push,
|
||||
store: opts.Store,
|
||||
notifier: opts.Notifier,
|
||||
typing: newTypingTracker(opts.TypingTimeout, opts.Notifier, opts.Now),
|
||||
|
||||
Reference in new issue
Block a user