From 6e5b7eb84b3ca8a902ac4bcbab9c2a9f9ecdee51 Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Tue, 27 Jan 2026 09:16:41 +0000 Subject: fix(sync): Remove .since() filter from database queries in load_existing_events() Root cause: `last_connected` was set to Timestamp::now() BEFORE load_existing_events() was called (line 425), causing the database query to filter out all existing events with .since(current_time). The query became: SELECT * FROM events WHERE created_at >= Result: 0 events returned (nothing has created_at in the future) Solution: Remove .since() filter from database queries entirely. The `last_connected` field is now only used for WebSocket subscription filters to avoid re-fetching events from remote relays on reconnect. Rationale for this approach over reordering operations: - Database queries are fast (indexed by kind and created_at) - Loading all events on startup ensures consistency - Eliminates subtle ordering dependency that could break in refactoring - Cleaner mental model: database = full load, WebSocket = incremental This fixes the issue where ~190 state events weren't being fetched after deploying the database query fix (commit 4162c90). Evidence: Production logs showed "Loaded announcements from database count=0" when there should have been hundreds of announcements. --- src/sync/self_subscriber.rs | 42 ++++++++---------------------------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/src/sync/self_subscriber.rs b/src/sync/self_subscriber.rs index e9505f1..86e4583 100644 --- a/src/sync/self_subscriber.rs +++ b/src/sync/self_subscriber.rs @@ -155,35 +155,18 @@ impl SelfSubscriber { /// 2. Second query: Get root events (1617/1618/1621) for handle_root_event() /// to add root event IDs for Layer 3 filter creation /// - /// Both queries use `.since(last_connected)` if available for incremental - /// loading on reconnect. - /// /// Returns a PendingUpdates containing all repos that need Layer 2/3 filters. async fn load_existing_events(&self) -> PendingUpdates { let mut pending = PendingUpdates::new(); - // Log whether this is a full or incremental load - if let Some(since) = self.last_connected { - tracing::info!( - since = %since, - "Loading events incrementally from database (reconnect)" - ); - } else { - tracing::info!("Loading all events from database (first connection)"); - } + tracing::info!("Loading all events from database"); - // First query: Get announcements to populate repo_sync_index - let mut announcement_filter = Filter::new().kind(Kind::GitRepoAnnouncement); - if let Some(timestamp) = self.last_connected { - announcement_filter = announcement_filter.since(timestamp); - } + // First query: Get all announcements to populate repo_sync_index + let announcement_filter = Filter::new().kind(Kind::GitRepoAnnouncement); let announcements = match self.database.query(announcement_filter).await { Ok(events) => { - tracing::info!( - count = events.len(), - "Loaded announcements from database" - ); + tracing::info!(count = events.len(), "Loaded announcements from database"); events } Err(e) => { @@ -219,22 +202,13 @@ impl SelfSubscriber { } } - // Second query: Get root events for handle_root_event() - let mut root_filter = Filter::new().kinds(vec![ - Kind::GitPatch, - Kind::GitIssue, - Kind::GitPullRequest, - ]); - if let Some(timestamp) = self.last_connected { - root_filter = root_filter.since(timestamp); - } + // Second query: Get all root events for handle_root_event() + let root_filter = + Filter::new().kinds(vec![Kind::GitPatch, Kind::GitIssue, Kind::GitPullRequest]); let root_events = match self.database.query(root_filter).await { Ok(events) => { - tracing::info!( - count = events.len(), - "Loaded root events from database" - ); + tracing::info!(count = events.len(), "Loaded root events from database"); events } Err(e) => { -- cgit v1.2.3