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