fix: periodic star recount every 5 minutes During backfill, stars arrive before repos so increment_repo_star_count misses. The recount task recomputes star_count from the stars table for any repo where the count is wrong.
Author: Aaron Steven White
Commit
ef94763fe68c0c3e76e05205a256c5de8ef91e32Parent: 71c9b0e8dc
Structural diff unavailable
These commits were pushed via plain git push, so no pre-parsed
schemas are available. Install git-remote-cospan and re-push via panproto:// to
see scope-level changes, breaking change detection, and semantic diffs.
brew install panproto/tap/git-remote-cospan2 files changed +38 -0
@@ -40,6 +40,27 @@ pub async fn decrement_repo_star_count(
4040 Ok(()) 4141 } 4242 43+/// Recompute all star counts from the stars table. 44+/// Handles backfill ordering where stars arrive before repos. 45+pub async fn recount_all_stars(pool: &PgPool) -> Result<u64, sqlx::Error> { 46+ let result = sqlx::query( 47+ "UPDATE repos SET star_count = COALESCE(s.cnt, 0) \ 48+ FROM ( \ 49+ SELECT \ 50+ split_part(replace(subject, 'at://', ''), '/', 1) AS repo_did, \ 51+ split_part(replace(subject, 'at://', ''), '/', 3) AS repo_rkey, \ 52+ COUNT(*) AS cnt \ 53+ FROM stars \ 54+ GROUP BY 1, 2 \ 55+ ) s \ 56+ WHERE repos.did = s.repo_did AND repos.rkey = s.repo_rkey \ 57+ AND repos.star_count <> s.cnt", 58+ ) 59+ .execute(pool) 60+ .await?; 61+ Ok(result.rows_affected()) 62+} 63+ 4364 pub async fn list_by_user( 4465 pool: &PgPool, 4566 did: &str,
@@ -77,6 +77,23 @@ async fn main() -> anyhow::Result<()> {
7777 } 7878 }); 7979 80+ // Periodic star recount (handles backfill ordering) 81+ let recount_pool = state.db.clone(); 82+ tokio::spawn(async move { 83+ loop { 84+ tokio::time::sleep(std::time::Duration::from_secs(300)).await; 85+ match cospan_appview::db::star::recount_all_stars(&recount_pool).await { 86+ Ok(updated) if updated > 0 => { 87+ tracing::info!(updated, "star recount complete"); 88+ } 89+ Ok(_) => {} 90+ Err(e) => { 91+ tracing::warn!(error = %e, "star recount failed"); 92+ } 93+ } 94+ } 95+ }); 96+ 8097 // Build and start the HTTP server 8198 let app = cospan_appview::xrpc::router(state); 8299 let listener = tokio::net::TcpListener::bind(&config.listen).await?;