use anyhow::Context;
use clap::Parser;
use reqwest::Client;
use serde::{Deserialize, Serialize};
use crate::commands::PROXY_HOST;
#[derive(Debug, Parser, Clone, Serialize, Deserialize)]
pub struct AddWorkers {
#[arg(value_name = "WORKERS", env = "MRP_PROXY_WORKERS_LIST", value_delimiter = ',')]
workers: Vec<String>,
#[arg(long, default_value = "8083", env = "MRP_CONTROL_PORT")]
control_port: u16,
}
#[derive(Debug, Parser, Clone, Serialize, Deserialize)]
pub struct RemoveWorkers {
#[arg(value_name = "WORKERS", env = "MRP_PROXY_WORKERS_LIST", value_delimiter = ',')]
workers: Vec<String>,
#[arg(long, default_value = "8083", env = "MRP_CONTROL_PORT")]
control_port: u16,
}
#[derive(clap::ValueEnum, Clone, Debug, Serialize, Deserialize)]
pub enum Action {
Add,
Remove,
}
#[derive(Debug, Parser, Clone, Serialize, Deserialize)]
pub struct UpdateWorkers {
pub action: Action,
pub workers: Vec<String>,
pub control_port: u16,
}
impl UpdateWorkers {
pub async fn execute(&self) -> anyhow::Result<()> {
let query_params = serde_qs::to_string(&self)?;
println!("Action: {:?}, with workers: {:?}", self.action, self.workers);
let url = format!("http://{}:{}?{}", PROXY_HOST, self.control_port, query_params);
let client = Client::builder().http2_prior_knowledge().build()?;
let response = client.get(url).send().await?;
if !response.status().is_success() {
anyhow::bail!("Request failed with status code: {}", response.status());
}
let workers_count = response
.headers()
.get("X-Worker-Count")
.context("Missing X-Worker-Count header")?
.to_str()?;
println!("New number of workers: {workers_count}");
Ok(())
}
}
impl From<RemoveWorkers> for UpdateWorkers {
fn from(remove_workers: RemoveWorkers) -> Self {
UpdateWorkers {
action: Action::Remove,
workers: remove_workers.workers,
control_port: remove_workers.control_port,
}
}
}
impl From<AddWorkers> for UpdateWorkers {
fn from(add_workers: AddWorkers) -> Self {
UpdateWorkers {
action: Action::Add,
workers: add_workers.workers,
control_port: add_workers.control_port,
}
}
}