refactor: split ReceiveServerConfig handler
All checks were successful
Rust / build (push) Successful in 1m48s
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/push-next Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful

First handler, with original name, validates the server config.

The new second handler, ReceiveValidServerConfig, can then (re)start the
server without needing to validate the settings.
This commit is contained in:
Paul Campbell 2024-07-11 08:06:36 +01:00
parent 4276964f4d
commit 7212154037

View file

@ -1,5 +1,6 @@
// //
use actix::prelude::*; use actix::prelude::*;
use derive_more::Constructor;
use git_next_actor_macros::message; use git_next_actor_macros::message;
use git_next_config as config; use git_next_config as config;
use git_next_config::server::{ServerConfig, ServerStorage, Webhook}; use git_next_config::server::{ServerConfig, ServerStorage, Webhook};
@ -9,18 +10,27 @@ use git_next_git::{Generation, RepoDetails};
use git_next_repo_actor::{messages::CloneRepo, RepoActor}; use git_next_repo_actor::{messages::CloneRepo, RepoActor};
use git_next_webhook_actor as webhook; use git_next_webhook_actor as webhook;
use kxio::{fs::FileSystem, network::Network}; use kxio::{fs::FileSystem, network::Network};
use std::path::PathBuf; use std::{net::SocketAddr, path::PathBuf};
use tracing::{error, info, warn}; use tracing::{error, info};
use webhook::{AddWebhookRecipient, ShutdownWebhook, WebhookActor, WebhookRouter}; use webhook::{AddWebhookRecipient, ShutdownWebhook, WebhookActor, WebhookRouter};
pub use git_next_git::repository::{factory::real as repository_factory, RepositoryFactory}; pub use git_next_git::repository::{factory::real as repository_factory, RepositoryFactory};
message!(ReceiveServerConfig: ServerConfig: "Notification of newly loaded server configuration. message!(ReceiveServerConfig: ServerConfig: "Notification of newly loaded server configuration.
This message will prompt the `git-next` server to stop and restart all repo-actors. This message will prompt the `git-next` server to stop and restart all repo-actors.
Contains the new server configuration."); Contains the new server configuration.");
#[derive(Clone, Debug, PartialEq, Eq, Constructor)]
pub struct ValidServerConfig {
server_config: ServerConfig,
socket_address: SocketAddr,
server_storage: ServerStorage,
}
message!(ReceiveValidServerConfig: ValidServerConfig: "Notification of validated server configuration.");
#[derive(Debug, derive_more::Display, derive_more::From)] #[derive(Debug, derive_more::Display, derive_more::From)]
pub enum Error { pub enum Error {
#[display("Failed to create data directories")] #[display("Failed to create data directories")]
@ -65,28 +75,45 @@ impl Handler<FileUpdated> for Server {
impl Handler<ReceiveServerConfig> for Server { impl Handler<ReceiveServerConfig> for Server {
type Result = (); type Result = ();
fn handle(&mut self, msg: ReceiveServerConfig, _ctx: &mut Self::Context) -> Self::Result { fn handle(&mut self, msg: ReceiveServerConfig, ctx: &mut Self::Context) -> Self::Result {
let Ok(socket_addr) = msg.http() else { let Ok(socket_addr) = msg.http() else {
warn!("Unable to parse http.addr"); error!("Unable to parse http.addr");
return; return;
}; };
let Some(server_storage) = self.server_storage(&msg) else {
error!("Server storage not available");
return;
};
ctx.address()
.do_send(ReceiveValidServerConfig::new(ValidServerConfig::new(
msg.0,
socket_addr,
server_storage,
)));
}
}
impl Handler<ReceiveValidServerConfig> for Server {
type Result = ();
fn handle(&mut self, msg: ReceiveValidServerConfig, _ctx: &mut Self::Context) -> Self::Result {
let ValidServerConfig {
server_config,
socket_address,
server_storage,
} = msg.0;
if let Some(webhook) = self.webhook.take() { if let Some(webhook) = self.webhook.take() {
webhook.do_send(ShutdownWebhook); webhook.do_send(ShutdownWebhook);
} }
self.generation.inc(); self.generation.inc();
let server_config = msg;
let Some(server_storage) = self.server_storage(&server_config) else {
return;
};
// Webhook Server // Webhook Server
info!("Starting Webhook Server..."); info!("Starting Webhook Server...");
let webhook_router = WebhookRouter::default().start(); let webhook_router = WebhookRouter::default().start();
let webhook = server_config.webhook(); let webhook = server_config.webhook();
// Forge Actors // Forge Actors
for (forge_alias, forge_config) in server_config.forges() { for (forge_alias, forge_config) in server_config.forges() {
self.create_forge_repos(forge_config, forge_alias.clone(), server_storage, webhook) self.create_forge_repos(forge_config, forge_alias.clone(), &server_storage, webhook)
.into_iter() .into_iter()
.map(|a| self.start_actor(a)) .map(|a| self.start_actor(a))
.map(|(repo_alias, addr)| { .map(|(repo_alias, addr)| {
@ -94,8 +121,7 @@ impl Handler<ReceiveServerConfig> for Server {
}) })
.for_each(|msg| webhook_router.do_send(msg)); .for_each(|msg| webhook_router.do_send(msg));
} }
let webhook = WebhookActor::new(socket_address, webhook_router.recipient()).start();
let webhook = WebhookActor::new(socket_addr, webhook_router.recipient()).start();
self.webhook.replace(webhook); self.webhook.replace(webhook);
} }
} }
@ -229,11 +255,8 @@ impl Server {
(repo_alias, addr) (repo_alias, addr)
} }
fn server_storage<'cfg>( fn server_storage(&self, server_config: &ReceiveServerConfig) -> Option<ServerStorage> {
&self, let server_storage = server_config.storage().clone();
server_config: &'cfg ReceiveServerConfig,
) -> Option<&'cfg ServerStorage> {
let server_storage = server_config.storage();
let dir = server_storage.path(); let dir = server_storage.path();
if !dir.exists() { if !dir.exists() {
if let Err(err) = self.fs.dir_create(dir) { if let Err(err) = self.fs.dir_create(dir) {