wire channel list RPC into consciousness F5 screen
fetch_all_channels() connects to each daemon socket and calls list() via capnp RPC. Runs on a dedicated thread (capnp uses Rc). Results sent back via mpsc channel, TUI reads cached state. Fetched at startup and when switching to F5 thalamus screen. Also calls ensure_running() to restart dead daemons. Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
e7be2a3ba0
commit
8e66f0a66c
4 changed files with 198 additions and 50 deletions
|
|
@ -176,3 +176,87 @@ impl ChannelManager {
|
|||
result
|
||||
}
|
||||
}
|
||||
|
||||
/// One-shot query: connect to a daemon socket, call list(), return results.
|
||||
/// Safe to call from any async context (no LocalSet needed).
|
||||
async fn query_one_daemon(sock: &std::path::Path) -> Vec<(String, bool, u32)> {
|
||||
let stream = match UnixStream::connect(sock).await {
|
||||
Ok(s) => s,
|
||||
Err(_) => return Vec::new(),
|
||||
};
|
||||
let (reader, writer) = stream.compat().split();
|
||||
let rpc_network = Box::new(twoparty::VatNetwork::new(
|
||||
futures::io::BufReader::new(reader),
|
||||
futures::io::BufWriter::new(writer),
|
||||
rpc_twoparty_capnp::Side::Client,
|
||||
Default::default(),
|
||||
));
|
||||
let mut rpc_system = RpcSystem::new(rpc_network, None);
|
||||
let client: channel_server::Client =
|
||||
rpc_system.bootstrap(rpc_twoparty_capnp::Side::Server);
|
||||
|
||||
let rpc_handle = tokio::task::spawn_local(async move {
|
||||
let _ = rpc_system.await;
|
||||
});
|
||||
|
||||
let mut result = Vec::new();
|
||||
if let Ok(reply) = client.list_request().send().promise.await {
|
||||
if let Ok(r) = reply.get() {
|
||||
if let Ok(channels) = r.get_channels() {
|
||||
for ch in channels.iter() {
|
||||
if let Ok(name) = ch.get_name() {
|
||||
result.push((
|
||||
name.to_str().unwrap_or("").to_string(),
|
||||
ch.get_connected(),
|
||||
ch.get_unread(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rpc_handle.abort();
|
||||
result
|
||||
}
|
||||
|
||||
/// Fetch channel status from all daemon sockets.
|
||||
/// Runs on a dedicated thread because capnp-rpc uses Rc (not Send).
|
||||
pub async fn fetch_all_channels() -> Vec<(String, bool, u32)> {
|
||||
tokio::task::spawn_blocking(|| {
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.unwrap();
|
||||
let local = tokio::task::LocalSet::new();
|
||||
local.block_on(&rt, fetch_all_channels_inner())
|
||||
})
|
||||
.await
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
async fn fetch_all_channels_inner() -> Vec<(String, bool, u32)> {
|
||||
let channels_dir = dirs::home_dir()
|
||||
.unwrap_or_default()
|
||||
.join(".consciousness/channels");
|
||||
|
||||
let mut sup = super::supervisor::Supervisor::new();
|
||||
sup.load_config();
|
||||
sup.ensure_running(); // restart any dead daemons
|
||||
|
||||
let mut result = Vec::new();
|
||||
for (daemon_name, _enabled, alive) in sup.status() {
|
||||
if !alive {
|
||||
result.push((daemon_name, false, 0));
|
||||
continue;
|
||||
}
|
||||
let sock = channels_dir.join(format!("{}.sock", daemon_name));
|
||||
let channels = query_one_daemon(&sock).await;
|
||||
if channels.is_empty() {
|
||||
result.push((daemon_name, false, 0));
|
||||
} else {
|
||||
result.extend(channels);
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue