-
Notifications
You must be signed in to change notification settings - Fork 53
Open
Description
Initial Problem
I've cloned the repo, and tried to run it with a simple cargo run.
However on Windows, the signal_hook::iterator::Signals
is not available.
I've come up with a solution, but I'm not yet too familiar with rust in general, so I'm fairly certain that there is a better solution.
What I did
I made two configurations one for #[cfg(not(windows))]
and one for #[cfg(windows)]
.
The one for not(windows)
is almost be unchanged.
The windows
config uses tokio::signal::windows
, instead of signal_hook
Let me know how I can improve this.
Other bugs
- When pressing a key to write, it is doubled.
- If I start the
cargo run
on my PC, and open chrome and go to the site universal-connectivity.on-fleek.app the two instances do not recognize/connect to each other. (If I've understood correctly this should not be the case)
Changed src/ui/headless.rs
file
#![allow(dead_code)]
use crate::{log::Message as LogMessage, ChatPeer, Message, Ui};
use async_trait::async_trait;
use libp2p::core::PeerId;
use std::{collections::HashSet, time::Duration};
use tokio::sync::mpsc::{self, Receiver, Sender};
use tokio_util::sync::CancellationToken;
/// A headless UI for the peer
pub struct Headless {
// my peer id
me: ChatPeer,
// we receive log messages from the log thread
from_log: Receiver<LogMessage>,
// we send UI messages to the peer thread
to_peer: Sender<Message>,
// we receive UI messages from the peer thread
from_peer: Receiver<Message>,
// the shutdown token
shutdown: CancellationToken,
// the list of peers
peers: HashSet<ChatPeer>,
}
impl Headless {
/// Create a new UI instance
pub fn build(
me: PeerId,
from_log: Receiver<LogMessage>,
shutdown: CancellationToken,
) -> (Box<dyn Ui + Send>, Sender<Message>, Receiver<Message>) {
// create a new channels for sending/receiving messages
let (to_peer, from_ui) = mpsc::channel::<Message>(64);
let (to_ui, from_peer) = mpsc::channel::<Message>(64);
// create a new TUI instance
let ui: Box<dyn Ui> = Box::new(Self {
me: me.into(),
from_log,
to_peer,
from_peer,
shutdown,
peers: HashSet::new(),
});
(ui, to_ui, from_ui)
}
}
#[async_trait]
impl Ui for Headless {
/// Run the UI
async fn run(&mut self) -> anyhow::Result<()> {
let mut signal_handle = None;
#[cfg(not(windows))]
{
use signal_hook::{consts::SIGTERM, iterator::Signals};
// Register the SIGTERM signal
signal_handle = Some(Signals::new([SIGTERM])?);
}
#[cfg(windows)]
{
use tokio::signal::windows::{ctrl_c, ctrl_break, ctrl_close, ctrl_logoff, ctrl_shutdown};
let mut ctrl_c_signal = ctrl_c()?;
let mut ctrl_break_signal = ctrl_break()?;
let mut ctrl_close_signal = ctrl_close()?;
let mut ctrl_logoff_signal = ctrl_logoff()?;
let mut ctrl_shutdown_signal = ctrl_shutdown()?;
signal_handle = Some(tokio::spawn(async move {
tokio::select! {
_ = ctrl_c_signal.recv() => {
println!("Received Ctrl+C signal.");
}
_ = ctrl_break_signal.recv() => {
println!("Received Ctrl+Break signal.");
}
_ = ctrl_close_signal.recv() => {
println!("Received Ctrl+Close signal.");
}
_ = ctrl_logoff_signal.recv() => {
println!("Received Ctrl+Logoff signal.");
}
_ = ctrl_shutdown_signal.recv() => {
println!("Received Ctrl+Shutdown signal.");
}
}
}));
}
println!("Headless UI started");
println!("Press Ctrl+C to exit");
println!("My peer id: {} ({})", self.me.id(), self.me);
// Main loop
'main: loop {
// Process log messages
if let Ok(log) = self.from_log.try_recv() {
//TODO: remove this after [PR 5966](https://github.com/libp2p/rust-libp2p/pull/5966)
if !log.message.starts_with("Can't send data channel") {
println!("{}", log.message);
}
}
// Process peer messages
if let Ok(ui_message) = self.from_peer.try_recv() {
match ui_message {
Message::Chat { from, data } => {
let from = from.map_or("Unknown".to_string(), |peer| peer.to_string());
let message =
String::from_utf8(data).unwrap_or("Invalid UTF-8".to_string());
println!("{}: {}", from, message);
}
Message::AddPeer(peer) => {
if self.peers.insert(peer) {
println!(
"Adding peer:\n\tpeer id: {}\n\tname: {}",
peer.id(),
peer.name()
);
}
}
Message::RemovePeer(peer) => {
if self.peers.remove(&peer) {
println!("Removing peer: {peer:?}");
}
}
Message::Event(event) => {
println!("{}", event);
}
_ => {}
}
}
// check if we have received the shutdown signal from the OS
#[cfg(not(windows))]
{
let signals = signal_handle.as_ref().unwrap();
if signals.pending().next() == Some(SIGTERM) {
println!("Received SIGTERM, shutting down");
self.shutdown.cancel();
break 'main;
}
}
#[cfg(windows)]
{
let handle = signal_handle.as_ref().unwrap();
if handle.is_finished() {
println!("Received SIGTERM, shutting down");
self.shutdown.cancel();
break 'main;
}
}
tokio::time::sleep(Duration::from_millis(18)).await;
}
Ok(())
}
}
Metadata
Metadata
Assignees
Labels
No labels