Skip to content

Commit

Permalink
implement reload configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
Keksoj committed Jan 10, 2024
1 parent 22cad6f commit 8908ad2
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 22 deletions.
2 changes: 1 addition & 1 deletion bin/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# "trace". For performance reasons, the logs at "debug" or "trace" level are
# not compiled by default. To activate them, pass the "logs-debug" and
# "logs-trace" compilation options to cargo
log_level = "debug"
log_level = "info"

# where the logs will be sent. It defaults to sending the logs on standard output,
# but they could be written to a UDP address:
Expand Down
2 changes: 1 addition & 1 deletion bin/src/command_v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub fn start_server(
command_hub.launch_new_worker();
}

load_static_config(&mut command_hub.server);
load_static_config(&mut command_hub.server, None, None);

if let Some(path) = saved_state_path {
requests::load_state(&mut command_hub.server, None, &path);
Expand Down
89 changes: 75 additions & 14 deletions bin/src/command_v2/requests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use mio::Token;
use nom::{HexDisplay, Offset};
use sozu_command_lib::{
buffer::fixed::Buffer,
config::Config,
logging,
parser::parse_several_requests,
proto::command::{
Expand Down Expand Up @@ -65,7 +66,9 @@ impl Server {
RequestType::UpgradeMain(_) => todo!(),
RequestType::UpgradeWorker(_) => todo!(),
RequestType::SubscribeEvents(_) => todo!(),
RequestType::ReloadConfiguration(_) => todo!(),
RequestType::ReloadConfiguration(path) => {
load_static_config(self, Some(client), Some(&path))
}
RequestType::Status(_) => status(self, client),
RequestType::AddCluster(_)
| RequestType::ActivateListener(_)
Expand Down Expand Up @@ -369,23 +372,45 @@ impl GatheringTask for QueryClustersTask {
#[derive(Debug)]
struct LoadStaticConfigTask {
gatherer: DefaultGatherer,
client_token: Option<Token>,
}

pub fn load_static_config(server: &mut Server) {
pub fn load_static_config(
server: &mut Server,
mut client: Option<&mut ClientSession>,
path: Option<&str>,
) {
let task_id = server.new_task(Box::new(LoadStaticConfigTask {
gatherer: DefaultGatherer::default(),
client_token: client.as_ref().map(|c| c.token.clone()),
}));

for (request_index, message) in server
.config
let new_config;

let config = match path {
Some(path) if !path.is_empty() => {
new_config = Config::load_from_path(path)
.expect(&format!("cannot load configuration from '{path}'"));
&new_config
}
_ => &server.config,
};

client.return_processing(format!(
"Reloading static configuration at path {}",
config.config_path
));

for (request_index, message) in config
.generate_config_messages()
.unwrap()
.into_iter()
.enumerate()
{
let request = message.content;
if let Err(error) = server.state.dispatch(&request) {
error!("Could not execute request on state: {:#}", error);
client.return_processing(format!("Could not execute request on state: {:#}", error));
continue;
}

if let &Some(RequestType::AddCertificate(_)) = &request.request_type {
Expand All @@ -397,24 +422,60 @@ pub fn load_static_config(server: &mut Server) {
server.scatter_on(request, task_id, request_index);
}
}
impl LoadStaticConfigTask {
fn finish(self, server: &mut Server, mut client: Option<&mut ClientSession>, _timed_out: bool) {
let mut messages = vec![];
for (worker_id, response) in self.gatherer.responses {
match response.status {
ResponseStatus::Ok => {}
ResponseStatus::Failure => {
messages.push(format!("worker {worker_id}: {}", response.message))
}
ResponseStatus::Processing => {}
}
}

if self.gatherer.errors > 0 {
client.finish_failure(format!(
"\nloading static configuration failed: {} OK, {} errors:\n- {}",
self.gatherer.ok,
self.gatherer.errors,
messages.join("\n- ")
));
} else {
client.finish_ok(
None,
format!(
"Successfully loaded the config: {} ok, {} errors",
self.gatherer.ok, self.gatherer.errors,
),
);
}

server.update_counts();
}
}

impl GatheringTask for LoadStaticConfigTask {
fn client_token(&self) -> Option<Token> {
None
self.client_token
}

fn get_gatherer(&mut self) -> &mut dyn Gatherer {
&mut self.gatherer
}

fn on_finish_no_client(self: Box<Self>, server: &mut Server, _timedout: bool) {
let DefaultGatherer { ok, errors, .. } = self.gatherer;
if errors == 0 {
info!("loading state: {} ok messages, 0 errors", ok);
} else {
error!("loading state: {} ok messages, {} errors", ok, errors);
}
server.update_counts();
fn on_finish(
self: Box<Self>,
server: &mut Server,
client: &mut ClientSession,
timed_out: bool,
) {
self.finish(server, Some(client), timed_out);
}

fn on_finish_no_client(self: Box<Self>, server: &mut Server, timed_out: bool) {
self.finish(server, None, timed_out);
}
}

Expand Down
17 changes: 11 additions & 6 deletions command/src/proto/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,17 @@ impl Response {
}
}

let content = match &self.content {
Some(content) => content,
None => return Ok(println!("No content")),
};

content.display(json)
match &self.content {
Some(content) => content.display(json),
None => {
if json {
println!("{{}}");
} else {
println!("No content");
}
Ok(())
}
}
}
}

Expand Down

0 comments on commit 8908ad2

Please sign in to comment.