git-next/crates/webhook-actor/src/router.rs

72 lines
2.2 KiB
Rust

//
use std::collections::BTreeMap;
use actix::prelude::*;
use derive_more::Constructor;
use git_next_config::{ForgeAlias, RepoAlias};
use git_next_repo_actor::messages::WebhookNotification;
use tracing::{debug, info};
pub struct WebhookRouter {
span: tracing::Span,
recipients: BTreeMap<ForgeAlias, BTreeMap<RepoAlias, Recipient<WebhookNotification>>>,
}
impl Default for WebhookRouter {
fn default() -> Self {
Self::new()
}
}
impl WebhookRouter {
pub fn new() -> Self {
let span = tracing::info_span!("WebhookRouter");
Self {
span,
recipients: Default::default(),
}
}
}
impl Actor for WebhookRouter {
type Context = Context<Self>;
}
impl Handler<WebhookNotification> for WebhookRouter {
type Result = ();
fn handle(&mut self, msg: WebhookNotification, _ctx: &mut Self::Context) -> Self::Result {
let _gaurd = self.span.enter();
let forge_alias = msg.forge_alias();
let repo_alias = msg.repo_alias();
debug!(forge = %forge_alias, repo = %repo_alias, "Router...");
let Some(forge_repos) = self.recipients.get(forge_alias) else {
return;
};
let Some(recipient) = forge_repos.get(repo_alias) else {
return;
};
info!(repo = %repo_alias, "Sending to Recipient");
recipient.do_send(msg);
}
}
#[derive(Message, Constructor)]
#[rtype(result = "()")]
pub struct AddWebhookRecipient {
pub forge_alias: ForgeAlias,
pub repo_alias: RepoAlias,
pub recipient: Recipient<WebhookNotification>,
}
impl Handler<AddWebhookRecipient> for WebhookRouter {
type Result = ();
fn handle(&mut self, msg: AddWebhookRecipient, _ctx: &mut Self::Context) -> Self::Result {
let _gaurd = self.span.enter();
info!(forge = %msg.forge_alias, repo = %msg.repo_alias, "Register Recipient");
if !self.recipients.contains_key(&msg.forge_alias) {
self.recipients
.insert(msg.forge_alias.clone(), BTreeMap::new());
}
self.recipients
.get_mut(&msg.forge_alias)
.map(|repos| repos.insert(msg.repo_alias, msg.recipient));
}
}