Skip to content

Commit

Permalink
feat(cli): fine-grain control over which sub-servers are started
Browse files Browse the repository at this point in the history
Instead of being given the option to start all of the sub-servers (`whirl run` or `whirl run all`),
you are now given the option to specify a selection of sub-servers by passing a comma-seperated list
to the `run` sub-command (`whirl run distributor,hub`). Despite the changes, `whirl run` still
starts all of the available sub-servers!
  • Loading branch information
Fuwn committed Jun 14, 2021
1 parent e4ead8c commit 27ec39f
Showing 1 changed file with 70 additions and 23 deletions.
93 changes: 70 additions & 23 deletions crates/whirl/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ enum RunType {
Distributor,
Hub,
Api,
All,
}
impl FromStr for RunType {
type Err = &'static str;
Expand All @@ -20,11 +19,28 @@ impl FromStr for RunType {
"distributor" => Ok(Self::Distributor),
"hub" => Ok(Self::Hub),
"api" => Ok(Self::Api),
_ => Ok(Self::All),
_ => Err("no match"),
}
}
}

// https://stackoverflow.com/questions/57888454/how-to-remove-duplicates-from-a-vector-of-structures
trait Dedup<T: PartialEq + Clone> {
fn clear_duplicates(&mut self);
}
impl<T: PartialEq + Clone> Dedup<T> for Vec<T> {
fn clear_duplicates(&mut self) {
let mut already_seen = vec![];
self.retain(|item| match already_seen.contains(item) {
true => false,
_ => {
already_seen.push(item.clone());
true
}
})
}
}

pub struct Cli;
impl Cli {
/// # Panics
Expand All @@ -50,13 +66,38 @@ impl Cli {
match matches.subcommand() {
("run", Some(s_matches)) =>
Self::run({
RunType::from_str(match s_matches.value_of("type") {
Some("distributor") => "distributor",
Some("hub") => "hub",
Some("api") => "api",
_ => "all",
})
.unwrap()
// Make a vector of the passed types for the `run` sub-command, if the
// vector cannot be unwrapped, the must mean that the user did not
// pass any sub-server types meaning that the subcommand `run` was
// called without any arguments, in other words: "run everything".
let mut types = {
// s_matches.values_of("type").unwrap().collect::<Vec<_>>();
match s_matches.values_of("type") {
Some(values) => values.collect::<Vec<_>>(),
None => vec!["distributor", "hub", "api"],
}
};
// Remove any duplicate sub-commands, we don't want to start two
// instances of the same sub-server.
types.clear_duplicates();

let mut run_types = vec![];
// Iterate over all of the types and push them to a vector that we'll
// pass to the `run` method.
loop {
match types.last() {
Some(run_type) => match run_type.to_owned() {
"distributor" => run_types.push(RunType::Distributor),
"hub" => run_types.push(RunType::Hub),
"api" => run_types.push(RunType::Api),
_ => {}
},
None => break,
}
types.pop();
}

run_types
})
.await,
("config", Some(s_matches)) =>
Expand Down Expand Up @@ -90,13 +131,17 @@ impl Cli {
.settings(&[AppSettings::SubcommandRequiredElseHelp])
.subcommands(vec![
SubCommand::with_name("run")
.about("Start the WorldServer or a single sub-server.")
.about("Start the WorldServer or a selection of sub-servers.")
.long_about("Start the WorldServer by running this sub-command \
WITHOUT any arguments, start a selection of sub-servers by passing a \
comma-separated list of sub-server types.")
.arg(
Arg::with_name("type")
.required(false)
.takes_value(true)
.index(1)
.possible_values(&["distributor", "hub", "api", "all"]),
.use_delimiter(true)
.possible_values(&["distributor", "hub", "api"]),
),
SubCommand::with_name("config")
.setting(AppSettings::SubcommandRequiredElseHelp)
Expand All @@ -111,18 +156,20 @@ impl Cli {
])
}

async fn run(server_type: RunType) {
match server_type {
RunType::Distributor => vec![whirl_server::make::distributor()],
RunType::Hub => vec![whirl_server::make::hub()],
RunType::Api => vec![whirl_api::make()],
RunType::All =>
vec![
whirl_api::make(),
whirl_server::make::distributor(),
whirl_server::make::hub(),
],
};
async fn run(mut server_type: Vec<RunType>) {
let mut threads = vec![];
// Iterate over all of of the requested sub-servers and spawn one of each.
loop {
match server_type.last() {
Some(run_type) => match run_type {
RunType::Distributor => threads.push(whirl_server::make::distributor()),
RunType::Hub => threads.push(whirl_server::make::hub()),
RunType::Api => threads.push(whirl_api::make()),
},
None => break,
}
server_type.pop();
}

if std::env::var("DISABLE_PROMPT").unwrap_or_else(|_| "false".to_string()) == "true"
|| !Config::get().whirlsplash.prompt.enable
Expand Down

1 comment on commit 27ec39f

@Fuwn
Copy link
Member Author

@Fuwn Fuwn commented on 27ec39f Jun 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks to Wirlaburla for the tip!

Please sign in to comment.