mirror of
https://github.com/stakwork/sphinx-key.git
synced 2025-12-17 23:34:19 +01:00
broker reconnection loop using tokio::select macro, both tx and rx
This commit is contained in:
@@ -6,7 +6,8 @@ default-run = "sphinx-key-broker"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
rumqttd = "0.11.0"
|
||||
# rumqttd = "0.11.0"
|
||||
rumqttd = { path = "../../rumqtt/rumqttd" }
|
||||
pretty_env_logger = "0.4.0"
|
||||
confy = "0.4.0"
|
||||
tokio = { version = "1.4.0", features = ["rt", "rt-multi-thread", "macros"] }
|
||||
@@ -20,6 +21,7 @@ fern = { version = "0.6", features = ["colored"] }
|
||||
rumqttc = "0.12.0"
|
||||
clap = "=3.0.0-beta.2"
|
||||
clap_derive = "=3.0.0-beta.5"
|
||||
chrono = "0.4"
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
mod mqtt;
|
||||
mod run_test;
|
||||
mod unix_fd;
|
||||
mod util;
|
||||
|
||||
use crate::mqtt::start_broker;
|
||||
use crate::unix_fd::SignerLoop;
|
||||
use clap::{App, AppSettings, Arg};
|
||||
use crate::mqtt::start_broker;
|
||||
use std::env;
|
||||
use tokio::sync::{mpsc, oneshot};
|
||||
use vls_proxy::client::UnixClient;
|
||||
use vls_proxy::connection::{open_parent_fd, UnixConnection};
|
||||
use vls_proxy::util::setup_logging;
|
||||
|
||||
pub struct Channel {
|
||||
pub sequence: u16,
|
||||
@@ -30,7 +30,12 @@ pub struct ChannelReply {
|
||||
fn main() -> anyhow::Result<()> {
|
||||
let parent_fd = open_parent_fd();
|
||||
|
||||
setup_logging("hsmd ", "info");
|
||||
/*
|
||||
simple_logger::SimpleLogger::new()
|
||||
.with_utc_timestamps()
|
||||
.with_module_level("async_io", log::LevelFilter::Off)
|
||||
*/
|
||||
util::setup_logging("hsmd ", "info");
|
||||
let app = App::new("signer")
|
||||
.setting(AppSettings::NoAutoVersion)
|
||||
.about("CLN:mqtt - connects to an embedded VLS over a MQTT connection")
|
||||
@@ -56,7 +61,8 @@ fn main() -> anyhow::Result<()> {
|
||||
run_test::run_test();
|
||||
} else {
|
||||
let (tx, rx) = mpsc::channel(1000);
|
||||
let _runtime = start_broker(true, rx);
|
||||
let (status_tx, status_rx) = mpsc::channel(1000);
|
||||
let _runtime = start_broker(rx, status_tx, "sphinx-1");
|
||||
// listen to reqs from CLN
|
||||
let conn = UnixConnection::new(parent_fd);
|
||||
let client = UnixClient::new(conn);
|
||||
|
||||
@@ -1,63 +1,118 @@
|
||||
use crate::{ChannelReply, ChannelRequest};
|
||||
use librumqttd::{async_locallink::construct_broker, Config};
|
||||
use librumqttd::{
|
||||
async_locallink::construct_broker,
|
||||
consolelink::{self, ConsoleLink},
|
||||
Config,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use tokio::sync::{mpsc, oneshot};
|
||||
use std::time::Duration;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
const SUB_TOPIC: &str = "sphinx-return";
|
||||
const PUB_TOPIC: &str = "sphinx";
|
||||
|
||||
pub fn start_broker(
|
||||
wait_for_ready_message: bool,
|
||||
mut receiver: mpsc::Receiver<ChannelRequest>,
|
||||
status_sender: mpsc::Sender<bool>,
|
||||
expected_client_id: &str,
|
||||
) -> tokio::runtime::Runtime {
|
||||
let config: Config = confy::load_path("config/rumqttd.conf").unwrap();
|
||||
let client_id = expected_client_id.to_string();
|
||||
|
||||
let (mut router, console, servers, builder) = construct_broker(config);
|
||||
let (mut router, servers, builder) = construct_broker(config.clone());
|
||||
|
||||
thread::spawn(move || {
|
||||
router.start().expect("could not start router");
|
||||
});
|
||||
|
||||
let mut client_connected = false;
|
||||
|
||||
// let (status_tx, mut status_rx): (mpsc::Sender<bool>, mpsc::Receiver<bool>) =
|
||||
// mpsc::channel(1000);
|
||||
|
||||
let mut rt_builder = tokio::runtime::Builder::new_multi_thread();
|
||||
rt_builder.enable_all();
|
||||
let rt = rt_builder.build().unwrap();
|
||||
rt.block_on(async {
|
||||
// channel to block until READY received
|
||||
let (ready_tx, ready_rx) = oneshot::channel();
|
||||
tokio::spawn(async move {
|
||||
let (msg_tx, mut msg_rx): (mpsc::Sender<Vec<u8>>, mpsc::Receiver<Vec<u8>>) =
|
||||
mpsc::channel(1000);
|
||||
let (mut tx, mut rx) = builder.connect("localclient", 200).await.unwrap();
|
||||
let (mut tx, mut rx) = builder.clone().connect("localclient", 200).await.unwrap();
|
||||
tx.subscribe([SUB_TOPIC]).await.unwrap();
|
||||
|
||||
let console_task = tokio::spawn(console);
|
||||
let router_tx = builder.router_tx();
|
||||
tokio::spawn(async move {
|
||||
let config = config.clone().into();
|
||||
let router_tx = router_tx.clone();
|
||||
let console: Arc<ConsoleLink> = Arc::new(ConsoleLink::new(config, router_tx));
|
||||
loop {
|
||||
let metrics = consolelink::request_metrics(console.clone(), client_id.clone());
|
||||
match metrics.tracker() {
|
||||
Some(t) => {
|
||||
// wait for subscription to be sure
|
||||
if t.concrete_subscriptions_len() > 0 {
|
||||
if !client_connected {
|
||||
println!("CLIENT CONNECTED!");
|
||||
client_connected = true;
|
||||
status_sender
|
||||
.send(true)
|
||||
.await
|
||||
.expect("couldnt send true statu");
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
if client_connected {
|
||||
println!("CLIENT DIsCONNECTED!");
|
||||
client_connected = false;
|
||||
status_sender
|
||||
.send(false)
|
||||
.await
|
||||
.expect("couldnt send false status");
|
||||
}
|
||||
}
|
||||
}
|
||||
tokio::time::sleep(Duration::from_millis(850)).await;
|
||||
}
|
||||
});
|
||||
|
||||
let sub_task = tokio::spawn(async move {
|
||||
// ready message loop
|
||||
// let ready_tx_ = ready_tx.clone();
|
||||
if wait_for_ready_message {
|
||||
loop {
|
||||
// wait for CONNECTED
|
||||
// loop {
|
||||
// let status = status_rx.recv().await.unwrap();
|
||||
// if status {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// now wait for READY
|
||||
// loop {
|
||||
// let message = rx.recv().await.unwrap();
|
||||
// if let Some(payload) = message.payload.get(0) {
|
||||
// let content = String::from_utf8_lossy(&payload[..]);
|
||||
// log::info!("received message content: {}", content);
|
||||
// if content == "READY" {
|
||||
// // ready_tx.send(true).expect("could not send ready");
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// now start parsing... or break for DISCONNECT
|
||||
println!("OK START PARSING!");
|
||||
loop {
|
||||
let message = rx.recv().await.unwrap();
|
||||
if let Some(payload) = message.payload.get(0) {
|
||||
let content = String::from_utf8_lossy(&payload[..]);
|
||||
log::info!("received message content: {}", content);
|
||||
if content == "READY" {
|
||||
ready_tx.send(true).expect("could not send ready");
|
||||
break;
|
||||
println!("T = {}, P = {:?}", message.topic, message.payload.len());
|
||||
// println!("count {}", message.payload.len());
|
||||
for payload in message.payload {
|
||||
if let Err(e) = msg_tx.send(payload.to_vec()).await {
|
||||
println!("pub err {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
loop {
|
||||
let message = rx.recv().await.unwrap();
|
||||
// println!("T = {}, P = {:?}", message.topic, message.payload.len());
|
||||
// println!("count {}", message.payload.len());
|
||||
for payload in message.payload {
|
||||
if let Err(e) = msg_tx.send(payload.to_vec()).await {
|
||||
println!("pub err {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let relay_task = tokio::spawn(async move {
|
||||
@@ -75,12 +130,7 @@ pub fn start_broker(
|
||||
servers.await;
|
||||
sub_task.await.unwrap();
|
||||
relay_task.await.unwrap();
|
||||
console_task.await.unwrap();
|
||||
});
|
||||
if wait_for_ready_message {
|
||||
log::info!("waiting for READY...");
|
||||
ready_rx.await.expect("Could not receive from channel.");
|
||||
}
|
||||
});
|
||||
|
||||
rt
|
||||
|
||||
@@ -12,16 +12,30 @@ pub fn run_test() {
|
||||
let mut sequence = 1;
|
||||
|
||||
let (tx, rx) = mpsc::channel(1000);
|
||||
let runtime = start_broker(true, rx);
|
||||
let (status_tx, mut status_rx) = mpsc::channel(1000);
|
||||
let runtime = start_broker(rx, status_tx, "test-1");
|
||||
log::info!("======> READY received! start now");
|
||||
runtime.block_on(async {
|
||||
let mut connected = false;
|
||||
loop {
|
||||
if let Err(e) = iteration(id, sequence, tx.clone()).await {
|
||||
panic!("iteration failed {:?}", e);
|
||||
}
|
||||
sequence = sequence.wrapping_add(1);
|
||||
id += 1;
|
||||
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
|
||||
tokio::select! {
|
||||
status = status_rx.recv() => {
|
||||
// println!("got a status");
|
||||
if let Some(connection_status) = status {
|
||||
connected = connected;
|
||||
println!("========> CONNETED! {}", connection_status);
|
||||
}
|
||||
}
|
||||
res = iteration(id, sequence, tx.clone(), connected) => {
|
||||
println!("iteration! connected: {}", connected);
|
||||
if let Err(e) = res {
|
||||
panic!("iteration failed {:?}", e);
|
||||
}
|
||||
sequence = sequence.wrapping_add(1);
|
||||
id += 1;
|
||||
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -30,7 +44,12 @@ pub async fn iteration(
|
||||
id: u16,
|
||||
sequence: u16,
|
||||
tx: mpsc::Sender<ChannelRequest>,
|
||||
connected: bool,
|
||||
) -> anyhow::Result<()> {
|
||||
if !connected {
|
||||
return Ok(());
|
||||
}
|
||||
println!("do a ping!");
|
||||
let ping = msgs::Ping {
|
||||
id,
|
||||
message: WireString("ping".as_bytes().to_vec()),
|
||||
|
||||
34
broker/src/util.rs
Normal file
34
broker/src/util.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
use std::env;
|
||||
use std::str::FromStr;
|
||||
|
||||
pub fn setup_logging(who: &str, level_arg: &str) {
|
||||
use fern::colors::{Color, ColoredLevelConfig};
|
||||
let colors = ColoredLevelConfig::new()
|
||||
.info(Color::Green)
|
||||
.error(Color::Red)
|
||||
.warn(Color::Yellow);
|
||||
let level = env::var("RUST_LOG").unwrap_or(level_arg.to_string());
|
||||
let who = who.to_string();
|
||||
fern::Dispatch::new()
|
||||
.format(move |out, message, record| {
|
||||
out.finish(format_args!(
|
||||
"[{} {}/{} {}] {}",
|
||||
chrono::Local::now().format("%Y-%m-%dT%H:%M:%S%.3f"),
|
||||
who,
|
||||
record.target(),
|
||||
colors.color(record.level()),
|
||||
message
|
||||
))
|
||||
})
|
||||
.level(log::LevelFilter::from_str(&level).expect("level"))
|
||||
.level_for("h2", log::LevelFilter::Info)
|
||||
.level_for("sled", log::LevelFilter::Info)
|
||||
.level_for(
|
||||
"librumqttd::rumqttlog::router::router",
|
||||
log::LevelFilter::Warn,
|
||||
)
|
||||
.chain(std::io::stdout())
|
||||
// .chain(fern::log_file("/tmp/output.log")?)
|
||||
.apply()
|
||||
.expect("log config");
|
||||
}
|
||||
@@ -47,15 +47,15 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
.await
|
||||
.expect("could not mqtt subscribe");
|
||||
|
||||
client
|
||||
.publish(
|
||||
PUB_TOPIC,
|
||||
QoS::AtMostOnce,
|
||||
false,
|
||||
"READY".as_bytes().to_vec(),
|
||||
)
|
||||
.await
|
||||
.expect("could not pub");
|
||||
// client
|
||||
// .publish(
|
||||
// PUB_TOPIC,
|
||||
// QoS::AtMostOnce,
|
||||
// false,
|
||||
// "READY".as_bytes().to_vec(),
|
||||
// )
|
||||
// .await
|
||||
// .expect("could not pub");
|
||||
|
||||
let matches = app.get_matches();
|
||||
if matches.is_present("test") {
|
||||
|
||||
Reference in New Issue
Block a user