refactor!: CQRS repository split — v0.3.0
FederationRepository (34 methods) → 4 focused traits:
ActivityRepository (2) — idempotency tracking
FollowRepository (18) — follower/following graph + migration
ActorRepository (6) — keypairs, remote actor cache, announce tracking
BlocklistRepository (8) — domain + actor blocklists
ApObjectHandler (10 methods) → 2 traits:
ApContentReader (3) — get_local_objects_for_user/page, count_local_posts
ApObjectHandler (9) — all inbox callbacks (on_create, on_mention, etc.)
Builder changes from positional args to named setters:
ActivityPubService::builder(base_url)
.activity_repo(arc)
.follow_repo(arc)
.actor_repo(arc)
.blocklist_repo(arc)
.user_repo(arc)
.content_reader(arc)
.object_handler(arc)
.build()
No behaviour changes.
This commit is contained in:
48
src/data.rs
48
src/data.rs
@@ -1,35 +1,25 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::content::ApObjectHandler;
|
||||
use crate::repository::FederationRepository;
|
||||
use crate::content::{ApContentReader, ApObjectHandler};
|
||||
use crate::repository::{ActivityRepository, ActorRepository, BlocklistRepository, FollowRepository};
|
||||
use crate::user::ApUserRepository;
|
||||
|
||||
/// Typed event emitted by the federation layer. Consumers wire in an
|
||||
/// [`EventPublisher`] to receive these and drive side effects (job queues,
|
||||
/// webhooks, metrics, etc.).
|
||||
/// Typed event emitted by the federation layer.
|
||||
///
|
||||
/// # Delivery flow
|
||||
///
|
||||
/// When an `EventPublisher` is configured, outbound activities are NOT
|
||||
/// When an [`EventPublisher`] is configured, outbound activities are NOT
|
||||
/// delivered directly — instead a [`FederationEvent::DeliveryRequested`] event
|
||||
/// is published for each target inbox. The consumer's job queue should:
|
||||
/// is published per inbox. The consumer's job queue should:
|
||||
/// 1. Persist the event.
|
||||
/// 2. Call [`crate::service::ActivityPubService::deliver_to_inbox`] when
|
||||
/// processing the queue item.
|
||||
/// 2. Call [`crate::service::ActivityPubService::deliver_to_inbox`] when processing.
|
||||
///
|
||||
/// Without a publisher, the library falls back to fire-and-forget
|
||||
/// `tokio::spawn` delivery (no persistence across restarts).
|
||||
/// Without a publisher, the library falls back to `tokio::spawn` delivery.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum FederationEvent {
|
||||
/// An outbound activity must be delivered to `inbox`.
|
||||
/// Call `ActivityPubService::deliver_to_inbox(inbox, activity, signing_actor_id)`.
|
||||
DeliveryRequested {
|
||||
inbox: url::Url,
|
||||
activity: serde_json::Value,
|
||||
signing_actor_id: uuid::Uuid,
|
||||
},
|
||||
/// Delivery to `inbox` failed permanently after all in-process retries.
|
||||
/// The consumer may schedule additional retries or alert.
|
||||
DeliveryFailed {
|
||||
inbox: url::Url,
|
||||
activity: serde_json::Value,
|
||||
@@ -38,10 +28,7 @@ pub enum FederationEvent {
|
||||
},
|
||||
}
|
||||
|
||||
/// Receives typed federation events from the library.
|
||||
///
|
||||
/// Implement this trait to bridge federation events into your application's
|
||||
/// job queue, message broker, or metrics system.
|
||||
/// Receives typed federation events.
|
||||
#[async_trait::async_trait]
|
||||
pub trait EventPublisher: Send + Sync {
|
||||
async fn publish(&self, event: FederationEvent) -> anyhow::Result<()>;
|
||||
@@ -49,8 +36,12 @@ pub trait EventPublisher: Send + Sync {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FederationData {
|
||||
pub(crate) federation_repo: Arc<dyn FederationRepository>,
|
||||
pub(crate) activity_repo: Arc<dyn ActivityRepository>,
|
||||
pub(crate) follow_repo: Arc<dyn FollowRepository>,
|
||||
pub(crate) actor_repo: Arc<dyn ActorRepository>,
|
||||
pub(crate) blocklist_repo: Arc<dyn BlocklistRepository>,
|
||||
pub(crate) user_repo: Arc<dyn ApUserRepository>,
|
||||
pub(crate) content_reader: Arc<dyn ApContentReader>,
|
||||
pub(crate) object_handler: Arc<dyn ApObjectHandler>,
|
||||
pub(crate) base_url: String,
|
||||
pub(crate) domain: String,
|
||||
@@ -60,9 +51,14 @@ pub struct FederationData {
|
||||
}
|
||||
|
||||
impl FederationData {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
federation_repo: Arc<dyn FederationRepository>,
|
||||
activity_repo: Arc<dyn ActivityRepository>,
|
||||
follow_repo: Arc<dyn FollowRepository>,
|
||||
actor_repo: Arc<dyn ActorRepository>,
|
||||
blocklist_repo: Arc<dyn BlocklistRepository>,
|
||||
user_repo: Arc<dyn ApUserRepository>,
|
||||
content_reader: Arc<dyn ApContentReader>,
|
||||
object_handler: Arc<dyn ApObjectHandler>,
|
||||
base_url: String,
|
||||
allow_registration: bool,
|
||||
@@ -77,8 +73,12 @@ impl FederationData {
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
Self {
|
||||
federation_repo,
|
||||
activity_repo,
|
||||
follow_repo,
|
||||
actor_repo,
|
||||
blocklist_repo,
|
||||
user_repo,
|
||||
content_reader,
|
||||
object_handler,
|
||||
base_url,
|
||||
domain,
|
||||
|
||||
Reference in New Issue
Block a user