rename: fetch_repository_data -> fetch_repository_data_{excluding,with}_purgatory

The old name was ambiguous - it wasn't clear whether purgatory was
included or not. The two variants are now explicitly named:
- fetch_repository_data_excluding_purgatory: DB only
- fetch_repository_data_with_purgatory: DB + purgatory overlay

SyncContext trait method also renamed to fetch_repository_data_with_purgatory
to match the free function it delegates to.
This commit is contained in:
DanConwayDev
2026-02-24 11:36:39 +00:00
parent 5efdf431a1
commit c31a313ccf
5 changed files with 45 additions and 35 deletions
+3 -3
View File
@@ -234,7 +234,7 @@ pub struct RepositoryData {
///
/// This performs a single database query to fetch both announcement and state events,
/// which is more efficient than separate queries.
pub async fn fetch_repository_data(
pub async fn fetch_repository_data_excluding_purgatory(
database: &SharedDatabase,
identifier: &str,
) -> Result<RepositoryData> {
@@ -298,7 +298,7 @@ pub async fn fetch_repository_data_with_purgatory(
identifier: &str,
) -> Result<RepositoryData> {
// First, fetch from database
let mut repo_data = fetch_repository_data(database, identifier).await?;
let mut repo_data = fetch_repository_data_excluding_purgatory(database, identifier).await?;
// Then, add announcements from purgatory
let purgatory_announcements = purgatory.get_announcements_by_identifier(identifier);
@@ -511,7 +511,7 @@ pub async fn get_authorization_from_db(
identifier: &str,
) -> Result<AuthorizationResult> {
// Fetch all repository data with a single query
let repo_data = fetch_repository_data(database, identifier).await?;
let repo_data = fetch_repository_data_excluding_purgatory(database, identifier).await?;
if repo_data.announcements.is_empty() {
return Ok(AuthorizationResult::denied(
+23 -22
View File
@@ -38,8 +38,8 @@ use tracing::{debug, info, warn};
use nostr_sdk::Event;
use crate::git::authorization::{
collect_authorized_maintainers, fetch_repository_data, fetch_repository_data_with_purgatory,
RepositoryData,
collect_authorized_maintainers, fetch_repository_data_excluding_purgatory,
fetch_repository_data_with_purgatory, RepositoryData,
};
use crate::git::{self, oid_exists};
use crate::nostr::builder::{Nip34WritePolicy, SharedDatabase};
@@ -933,20 +933,21 @@ async fn process_purgatory_state_events(
// IMPORTANT: Use fetch_repository_data_with_purgatory to include announcements
// that may still be in purgatory (not yet promoted). This ensures authorization
// works correctly even if the announcement promotion happens in the same batch.
let mut db_repo_data = match fetch_repository_data_with_purgatory(database, purgatory, identifier).await {
Ok(data) => data,
Err(e) => {
warn!(
identifier = %identifier,
error = %e,
"Failed to fetch repository data for purgatory state events"
);
result
.errors
.push(format!("Failed to fetch repo data: {}", e));
return result;
}
};
let mut db_repo_data =
match fetch_repository_data_with_purgatory(database, purgatory, identifier).await {
Ok(data) => data,
Err(e) => {
warn!(
identifier = %identifier,
error = %e,
"Failed to fetch repository data for purgatory state events"
);
result
.errors
.push(format!("Failed to fetch repo data: {}", e));
return result;
}
};
// Process each state event in chronological order
for entry in &purgatory_states {
@@ -1231,7 +1232,7 @@ async fn process_purgatory_pr_events(
// NOTE: Only fetch from database, NOT purgatory. PR events should only be
// released from purgatory when the announcement has been promoted (validated).
// This ensures we don't accept PR events for announcements that fail validation.
let db_repo_data = match fetch_repository_data(database, identifier).await {
let db_repo_data = match fetch_repository_data_excluding_purgatory(database, identifier).await {
Ok(data) => data,
Err(e) => {
warn!(
@@ -1372,7 +1373,9 @@ async fn process_purgatory_announcements(
error = %e,
"Failed to parse owner pubkey"
);
result.errors.push(format!("Failed to parse owner pubkey: {}", e));
result
.errors
.push(format!("Failed to parse owner pubkey: {}", e));
return result;
}
};
@@ -1450,10 +1453,8 @@ async fn process_purgatory_announcements(
}
// Re-process events from hot cache
let dummy_addr = SocketAddr::new(
IpAddr::V4(Ipv4Addr::LOCALHOST),
0,
);
let dummy_addr =
SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 0);
for hot_event in hot_events {
info!(
event_id = %hot_event.id,
+3 -3
View File
@@ -7,7 +7,7 @@ use nostr_relay_builder::prelude::Event;
use super::PolicyContext;
use crate::git;
use crate::git::authorization::{collect_authorized_maintainers, fetch_repository_data};
use crate::git::authorization::{collect_authorized_maintainers, fetch_repository_data_excluding_purgatory};
/// Policy for validating PR and PR Update events
#[derive(Clone)]
@@ -131,7 +131,7 @@ impl PrEventPolicy {
// only be accepted for announcements that have been promoted (validated).
// If the announcement is still in purgatory, the PR event should also go
// to purgatory and wait for the announcement to be promoted.
let db_repo_data = fetch_repository_data(&self.ctx.database, &identifier).await?;
let db_repo_data = fetch_repository_data_excluding_purgatory(&self.ctx.database, &identifier).await?;
// Extract owner pubkey from source repo path
let owner_pubkey = crate::git::sync::extract_owner_from_repo_path(
@@ -211,7 +211,7 @@ impl PrEventPolicy {
// only be accepted for announcements that have been promoted (validated).
// If the announcement is still in purgatory, the PR event should also go
// to purgatory and wait for the announcement to be promoted.
let db_repo_data = fetch_repository_data(&self.ctx.database, identifier).await?;
let db_repo_data = fetch_repository_data_excluding_purgatory(&self.ctx.database, identifier).await?;
// 3. Extract list of maintainers from "a 30617:<maintainer>:<identifier>" tags
let mut maintainer_pubkeys = std::collections::HashSet::new();
+13 -4
View File
@@ -87,7 +87,10 @@ pub trait SyncContext: Send + Sync {
///
/// # Returns
/// Repository data including announcements and state events
async fn fetch_repository_data(&self, identifier: &str) -> Result<RepositoryData>;
async fn fetch_repository_data_with_purgatory(
&self,
identifier: &str,
) -> Result<RepositoryData>;
/// Get all OIDs needed for purgatory events with this identifier.
///
@@ -283,7 +286,10 @@ impl SyncContext for RealSyncContext {
urls
}
async fn fetch_repository_data(&self, identifier: &str) -> Result<RepositoryData> {
async fn fetch_repository_data_with_purgatory(
&self,
identifier: &str,
) -> Result<RepositoryData> {
// Use the purgatory-aware variant so that clone URLs from announcements still
// in purgatory (not yet promoted) are available. Without this, the sync loop
// would find no URLs to fetch from and the announcement could never be promoted
@@ -585,7 +591,7 @@ pub mod mock {
/// assert_eq!(mock.fetch_log(), vec!["https://github.com/foo/bar.git"]);
/// ```
pub struct MockSyncContext {
/// Repository data to return from fetch_repository_data
/// Repository data to return from fetch_repository_data_with_purgatory
repo_data: RwLock<Option<RepositoryData>>,
/// Clone URLs available for the repository (from announcements)
@@ -732,7 +738,10 @@ pub mod mock {
self.pr_clone_urls.clone()
}
async fn fetch_repository_data(&self, _identifier: &str) -> Result<RepositoryData> {
async fn fetch_repository_data_with_purgatory(
&self,
_identifier: &str,
) -> Result<RepositoryData> {
// Return stored repo_data or create a minimal one with clone URLs
if let Some(data) = self.repo_data.read().unwrap().as_ref() {
// Clone the data - this is a test mock so efficiency isn't critical
+3 -3
View File
@@ -104,7 +104,7 @@ pub async fn sync_identifier_next_url<C: SyncContext + ?Sized>(
}
// 3. Get repository data
let repo_data = match ctx.fetch_repository_data(identifier).await {
let repo_data = match ctx.fetch_repository_data_with_purgatory(identifier).await {
Ok(data) => data,
Err(e) => {
debug!(
@@ -228,7 +228,7 @@ pub async fn get_throttled_domains_with_untried_urls<C: SyncContext + ?Sized>(
throttle_manager: &ThrottleManager,
git_naughty_list: &NaughtyListTracker,
) -> Vec<ThrottledDomainInfo> {
let repo_data = match ctx.fetch_repository_data(identifier).await {
let repo_data = match ctx.fetch_repository_data_with_purgatory(identifier).await {
Ok(data) => data,
Err(_) => return vec![],
};
@@ -333,7 +333,7 @@ pub async fn sync_identifier_from_url<C: SyncContext + ?Sized>(
};
// Get repository data for target repo path
let repo_data = match ctx.fetch_repository_data(identifier).await {
let repo_data = match ctx.fetch_repository_data_with_purgatory(identifier).await {
Ok(data) => data,
Err(e) => {
debug!(