Skip to content

Commit

Permalink
feat: add daemon mode
Browse files Browse the repository at this point in the history
Closes #41
  • Loading branch information
lowitea committed Jan 28, 2025
1 parent fd36248 commit 0cd689e
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 62 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ cargo pike run --topology topology.toml --data-dir ./tmp
- `--picodata-path <BINARY_PATH>` - Путь до исполняемого файла Пикодаты. Значение по умолчанию: `picodata`
- `--release` - Сборка и запуск релизной версии плагина
- `--target-dir <TARGET_DIR>` - Директория собранных бинарных файлов. Значение по умолчанию: `target`
- `-d, --daemon` - Запуск кластера в режиме демона

#### config.yaml

Expand Down
29 changes: 16 additions & 13 deletions src/commands/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,10 +268,11 @@ pub fn cmd(
base_pg_port: i32,
use_release: bool,
target_dir: &Path,
daemon: bool,
) -> Result<()> {
fs::create_dir_all(data_dir).unwrap();

{
if !daemon {
ctrlc::set_handler(move || {
info!("{}", "received Ctrl+C. Shutting down ...");

Expand All @@ -296,18 +297,20 @@ pub fn cmd(

// Run in the loop until the child processes are killed
// with cargo stop or Ctrl+C signal is recieved
loop {
thread::sleep(std::time::Duration::from_millis(100));
let processes_lock = Arc::clone(&get_picodata_processes());
let mut processes = processes_lock.lock().unwrap();

let all_proccesses_ended = processes
.iter_mut()
.all(|p| p.try_wait().unwrap().is_some());

if all_proccesses_ended {
info!("{}", "all child processes have ended, shutting down...");
break;
if !daemon {
loop {
thread::sleep(std::time::Duration::from_millis(100));
let processes_lock = Arc::clone(&get_picodata_processes());
let mut processes = processes_lock.lock().unwrap();

let all_proccesses_ended = processes
.iter_mut()
.all(|p| p.try_wait().unwrap().is_some());

if all_proccesses_ended {
info!("{}", "all child processes have ended, shutting down...");
break;
}
}
}

Expand Down
113 changes: 64 additions & 49 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ enum Command {
/// Change target folder
#[arg(long, value_name = "TARGET_DIR", default_value = "target")]
target_dir: PathBuf,
// TODO: add demon flag, if true then set output logs to file and release stdin
/// Run cluster in background
#[arg(long, short)]
daemon: bool,
},
/// Stop Picodata cluster
Stop {
Expand Down Expand Up @@ -131,8 +133,16 @@ enum Config {
/// # Safety
///
/// This function is safe because it uses safety functions from `libc` without side effects.
fn child_killer(master_pid: u32) {
fn run_child_killer() {
let master_pid = std::process::id();

unsafe {
match fork() {
Ok(ForkResult::Parent { .. }) => return,
Ok(ForkResult::Child) => (),
Err(_) => log::warn!("Error run supervisor process"),
}

libc::setsid();
}

Expand All @@ -152,16 +162,6 @@ fn child_killer(master_pid: u32) {
}

fn main() -> Result<()> {
let self_pid = std::process::id();

unsafe {
match fork() {
Ok(ForkResult::Parent { .. }) => (),
Ok(ForkResult::Child) => child_killer(self_pid),
Err(_) => log::warn!("Error run supervisor process"),
}
}

colog::init();
let cli = Cli::parse_from(env::args().skip(1));

Expand All @@ -175,51 +175,66 @@ fn main() -> Result<()> {
base_pg_port,
release,
target_dir,
} => commands::run::cmd(
&topology,
&data_dir,
disable_plugin_install,
base_http_port,
&picodata_path,
base_pg_port,
release,
&target_dir,
)
.context("failed to execute Run command")?,
daemon,
} => {
if !daemon {
run_child_killer()
}
commands::run::cmd(
&topology,
&data_dir,
disable_plugin_install,
base_http_port,
&picodata_path,
base_pg_port,
release,
&target_dir,
daemon,
)
.context("failed to execute Run command")?
}
Command::Stop { data_dir } => {
run_child_killer();
commands::stop::cmd(&data_dir).context("failed to execute \"stop\" command")?;
}
Command::Clean { data_dir } => {
run_child_killer();
commands::clean::cmd(&data_dir).context("failed to execute \"clean\" command")?;
}
Command::Plugin { command } => match command {
Plugin::Pack { debug, target_dir } => {
commands::plugin::pack::cmd(debug, &target_dir)
.context("failed to execute \"pack\" command")?;
Command::Plugin { command } => {
run_child_killer();
match command {
Plugin::Pack { debug, target_dir } => {
commands::plugin::pack::cmd(debug, &target_dir)
.context("failed to execute \"pack\" command")?;
}
Plugin::Build { release } => {
commands::plugin::build::cmd(release)
.context("failed to execute \"build\" command")?;
}
Plugin::New {
path,
without_git,
workspace,
} => commands::plugin::new::cmd(Some(&path), without_git, workspace)
.context("failed to execute \"plugin new\" command")?,
Plugin::Init {
without_git,
workspace,
} => commands::plugin::new::cmd(None, without_git, workspace)
.context("failed to execute \"init\" command")?,
}
Plugin::Build { release } => {
commands::plugin::build::cmd(release)
.context("failed to execute \"build\" command")?;
}
Command::Config { command } => {
run_child_killer();
match command {
Config::Apply {
config_path,
data_dir,
} => commands::config::apply::cmd(&config_path, &data_dir)
.context("failed to execute \"config apply\" command")?,
}
Plugin::New {
path,
without_git,
workspace,
} => commands::plugin::new::cmd(Some(&path), without_git, workspace)
.context("failed to execute \"plugin new\" command")?,
Plugin::Init {
without_git,
workspace,
} => commands::plugin::new::cmd(None, without_git, workspace)
.context("failed to execute \"init\" command")?,
},
Command::Config { command } => match command {
Config::Apply {
config_path,
data_dir,
} => commands::config::apply::cmd(&config_path, &data_dir)
.context("failed to execute \"config apply\" command")?,
},
}
};

Ok(())
Expand Down

0 comments on commit 0cd689e

Please sign in to comment.