2 Commits

Author SHA1 Message Date
bb7db58848 chore: add tracing to inbox, delivery, actor cache
All checks were successful
CI / fmt (push) Successful in 31s
CI / clippy (push) Successful in 4m0s
CI / test (push) Successful in 5m55s
2026-07-11 10:39:43 +02:00
6e1e1357fb fix: treat fetched_at=None as stale, bump 0.4.4 2026-07-11 10:37:11 +02:00
6 changed files with 33 additions and 4 deletions

View File

@@ -1,5 +1,17 @@
# Changelog
## [0.4.4] — 2026-07-11
### Bug fixes
- Actor cache TTL now treats `fetched_at: None` as always-stale instead of always-fresh. Consumers who never populated `fetched_at` were silently getting no cache invalidation.
### Other improvements
- Structured tracing on key code paths: inbound activity dispatch (activity ID, source domain), outbound delivery (inbox count, retry attempts), actor cache lookups (hit/miss, staleness).
---
## [0.4.3] — 2026-07-11
### Bug fixes

2
Cargo.lock generated
View File

@@ -1368,7 +1368,7 @@ dependencies = [
[[package]]
name = "k-ap"
version = "0.4.3"
version = "0.4.4"
dependencies = [
"activitypub_federation",
"anyhow",

View File

@@ -1,6 +1,6 @@
[package]
name = "k-ap"
version = "0.4.3"
version = "0.4.4"
edition = "2024"
description = "Generic ActivityPub protocol layer"
license = "MIT"

View File

@@ -35,10 +35,11 @@ pub(crate) async fn check_guards(
actor: &Url,
data: &Data<FederationData>,
) -> Result<bool, Error> {
let domain = actor.host_str().unwrap_or("");
tracing::info!(activity_id = %id, source_domain = domain, "processing inbound activity");
if already_processed(id, data).await {
return Ok(true);
}
let domain = actor.host_str().unwrap_or("");
if data.blocklist_repo.is_domain_blocked(domain).await? {
tracing::info!(actor = %actor, "ignoring activity from blocked domain");
return Ok(true);

View File

@@ -16,6 +16,11 @@ pub(crate) async fn send_with_retry(
max_attempts: u32,
initial_delay_secs: u64,
) -> Vec<anyhow::Error> {
tracing::info!(
inbox_count = sends.len(),
max_attempts,
"starting outbound delivery"
);
let mut failures = vec![];
for send in sends {
let mut delay = std::time::Duration::from_secs(initial_delay_secs);

View File

@@ -39,10 +39,21 @@ impl ActivityPubService {
let age = chrono::Utc::now().signed_duration_since(t);
age < chrono::Duration::from_std(data.actor_cache_ttl).unwrap_or_default()
})
.unwrap_or(true);
.unwrap_or_else(|| {
tracing::debug!(actor_url, "fetched_at is None, treating as stale — consider populating fetched_at in get_remote_actor()");
false
});
tracing::debug!(
actor_url,
cache_hit = true,
fresh = is_fresh,
"actor cache lookup"
);
if is_fresh {
return Ok(cached);
}
} else {
tracing::debug!(actor_url, cache_hit = false, "actor cache lookup");
}
let url = match Url::parse(actor_url) {
Ok(u) => u,