Initial commit
commit
f1160846db
|
@ -0,0 +1 @@
|
||||||
|
/target
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "luci"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
etcd-client = { version = "0.14.0", features = ["tls"] }
|
||||||
|
tokio = { version = "1.39.1", default-features = false, features = ["rt", "macros", "rt-multi-thread", "signal"] }
|
||||||
|
tracing = "0.1.40"
|
||||||
|
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
|
@ -0,0 +1,101 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use etcd_client::Client;
|
||||||
|
use tokio::sync::Notify;
|
||||||
|
use tokio::signal::unix::SignalKind;
|
||||||
|
use tracing::{debug, info, error, trace};
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
tracing_subscriber::fmt()
|
||||||
|
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
|
||||||
|
.with_writer(std::io::stderr)
|
||||||
|
.init();
|
||||||
|
|
||||||
|
let stop = Arc::new(Notify::new());
|
||||||
|
let my_stop = stop.clone();
|
||||||
|
let task = tokio::spawn(async move {
|
||||||
|
run(&stop).await
|
||||||
|
});
|
||||||
|
if let Err(e) = wait_signal().await {
|
||||||
|
error!("Failed to set up signal handler: {}", e);
|
||||||
|
std::process::exit(1);
|
||||||
|
};
|
||||||
|
my_stop.notify_waiters();
|
||||||
|
if let Err(e) = task.await {
|
||||||
|
error!("{}", e);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn run(stop: &Notify) {
|
||||||
|
loop {
|
||||||
|
let mut client = tokio::select! {
|
||||||
|
c = connect() => c,
|
||||||
|
_ = stop.notified() => return
|
||||||
|
};
|
||||||
|
let (_, mut stream) = match client.watch("dustin", None).await {
|
||||||
|
Ok((w, s)) => (w, s),
|
||||||
|
Err(e) => {
|
||||||
|
error!("Error setting up watch: {}", e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
info!("Watch stream established");
|
||||||
|
tokio::select! {
|
||||||
|
m = stream.message() => {
|
||||||
|
trace!("{:?}", m);
|
||||||
|
}
|
||||||
|
_ = stop.notified() => break,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
info!("Shutting down");
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn connect() -> Client {
|
||||||
|
let mut duration = Duration::from_millis(250);
|
||||||
|
let addrs = [
|
||||||
|
"http://127.0.0.1:2379",
|
||||||
|
];
|
||||||
|
loop {
|
||||||
|
let mut client = match Client::connect(&addrs, None).await {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(e) => {
|
||||||
|
error!("Failed to connect to etcd: {}", e);
|
||||||
|
tokio::time::sleep(duration).await;
|
||||||
|
if duration.as_secs() < 300 {
|
||||||
|
duration *= 2;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Client::connect() always succeeds?
|
||||||
|
match client.status().await {
|
||||||
|
Ok(s) => info!("Connected: {:?}", s),
|
||||||
|
Err(e) => {
|
||||||
|
error!("Failed to connect to etcd: {}", e);
|
||||||
|
tokio::time::sleep(duration).await;
|
||||||
|
if duration.as_secs() < 300 {
|
||||||
|
duration *= 2;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_signal() -> std::io::Result<()> {
|
||||||
|
let mut sigterm = tokio::signal::unix::signal(SignalKind::terminate())?;
|
||||||
|
let mut sigint = tokio::signal::unix::signal(SignalKind::interrupt())?;
|
||||||
|
tokio::select! {
|
||||||
|
_ = sigterm.recv() => {
|
||||||
|
debug!("Got signal SIGTERM");
|
||||||
|
}
|
||||||
|
_ = sigint.recv() => {
|
||||||
|
debug!("Got signal SIGINT");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in New Issue