Test against mock rpc server
This commit is contained in:
parent
fec725bc52
commit
c455c1fbbe
7 changed files with 82 additions and 289 deletions
|
|
@ -2,7 +2,7 @@ use super::*;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
const RECONNECT_POLL_TIME: Duration = Duration::from_secs(5);
|
const RECONNECT_POLL_TIME: Duration = Duration::from_secs(3);
|
||||||
|
|
||||||
pub struct App {
|
pub struct App {
|
||||||
daemon_client: Arc<Mutex<Option<Channel>>>,
|
daemon_client: Arc<Mutex<Option<Channel>>>,
|
||||||
|
|
@ -58,7 +58,16 @@ impl AsyncComponent for App {
|
||||||
root: Self::Root,
|
root: Self::Root,
|
||||||
sender: AsyncComponentSender<Self>,
|
sender: AsyncComponentSender<Self>,
|
||||||
) -> AsyncComponentParts<Self> {
|
) -> AsyncComponentParts<Self> {
|
||||||
let daemon_client = Arc::new(Mutex::new(daemon::daemon_connect().await.ok()));
|
// TODO: RPC REFACTOR (Handle Error)
|
||||||
|
let mut daemon_client_connected = false;
|
||||||
|
let daemon_client = Arc::new(Mutex::new(
|
||||||
|
daemon::daemon_connect()
|
||||||
|
.await
|
||||||
|
.inspect(|_| {
|
||||||
|
daemon_client_connected = true;
|
||||||
|
})
|
||||||
|
.ok(),
|
||||||
|
));
|
||||||
|
|
||||||
let main_screen = main_screen::MainScreen::builder()
|
let main_screen = main_screen::MainScreen::builder()
|
||||||
.launch(main_screen::MainScreenInit {
|
.launch(main_screen::MainScreenInit {
|
||||||
|
|
@ -72,6 +81,17 @@ impl AsyncComponent for App {
|
||||||
})
|
})
|
||||||
.forward(sender.input_sender(), |_| AppMsg::None);
|
.forward(sender.input_sender(), |_| AppMsg::None);
|
||||||
|
|
||||||
|
if !daemon_client_connected {
|
||||||
|
main_screen
|
||||||
|
.sender()
|
||||||
|
.send(main_screen::MainScreenMsg::DaemonDisconnect)
|
||||||
|
.unwrap();
|
||||||
|
settings_screen
|
||||||
|
.sender()
|
||||||
|
.send(settings_screen::SettingsScreenMsg::DaemonStateChange)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
|
|
||||||
let view_stack = adw::ViewStack::new();
|
let view_stack = adw::ViewStack::new();
|
||||||
|
|
@ -126,16 +146,21 @@ impl AsyncComponent for App {
|
||||||
let mut daemon_client = self.daemon_client.lock().await;
|
let mut daemon_client = self.daemon_client.lock().await;
|
||||||
let mut disconnected_daemon_client = false;
|
let mut disconnected_daemon_client = false;
|
||||||
|
|
||||||
if let Some(daemon_client) = daemon_client.as_mut() {
|
if let Some(client) = daemon_client.as_mut() {
|
||||||
let mut client = tunnel_client::TunnelClient::new(daemon_client);
|
let mut client = tunnel_client::TunnelClient::new(client);
|
||||||
if let Err(_e) = client.tunnel_status(burrow_rpc::Empty {}).await {
|
|
||||||
|
if let Ok(mut res) = client.tunnel_status(burrow_rpc::Empty {}).await {
|
||||||
|
let stream = res.get_mut();
|
||||||
|
while let Ok(Some(_)) = stream.message().await {}
|
||||||
|
}
|
||||||
|
|
||||||
|
*daemon_client = None;
|
||||||
disconnected_daemon_client = true;
|
disconnected_daemon_client = true;
|
||||||
self.main_screen
|
self.main_screen
|
||||||
.emit(main_screen::MainScreenMsg::DaemonDisconnect);
|
.emit(main_screen::MainScreenMsg::DaemonDisconnect);
|
||||||
self.settings_screen
|
self.settings_screen
|
||||||
.emit(settings_screen::SettingsScreenMsg::DaemonStateChange)
|
.emit(settings_screen::SettingsScreenMsg::DaemonStateChange)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if disconnected_daemon_client || daemon_client.is_none() {
|
if disconnected_daemon_client || daemon_client.is_none() {
|
||||||
match daemon::daemon_connect().await {
|
match daemon::daemon_connect().await {
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,4 @@ mod switch;
|
||||||
|
|
||||||
pub use network_card::{NetworkCard, NetworkCardInit};
|
pub use network_card::{NetworkCard, NetworkCardInit};
|
||||||
pub use networks::{Networks, NetworksInit};
|
pub use networks::{Networks, NetworksInit};
|
||||||
pub use switch::{Switch, SwitchInit, SwitchMsg};
|
pub use switch::{Switch, SwitchInit};
|
||||||
|
|
|
||||||
|
|
@ -86,30 +86,28 @@ impl AsyncComponent for NetworkCard {
|
||||||
async fn update(
|
async fn update(
|
||||||
&mut self,
|
&mut self,
|
||||||
msg: Self::Input,
|
msg: Self::Input,
|
||||||
sender: AsyncComponentSender<Self>,
|
_: AsyncComponentSender<Self>,
|
||||||
_root: &Self::Root,
|
_root: &Self::Root,
|
||||||
) {
|
) {
|
||||||
match msg {
|
match msg {
|
||||||
NetworkCardMsg::NetworkDelete => {
|
NetworkCardMsg::NetworkDelete => {
|
||||||
if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() {
|
if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() {
|
||||||
let mut client = networks_client::NetworksClient::new(daemon_client);
|
let mut client = networks_client::NetworksClient::new(daemon_client);
|
||||||
client
|
let _ = client
|
||||||
.network_delete(burrow_rpc::NetworkDeleteRequest { id: self.id })
|
.network_delete(burrow_rpc::NetworkDeleteRequest { id: self.id })
|
||||||
.await
|
.await;
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NetworkCardMsg::MoveUp => {
|
NetworkCardMsg::MoveUp => {
|
||||||
if self.index.checked_sub(1).is_some() {
|
if self.index.checked_sub(1).is_some() {
|
||||||
if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() {
|
if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() {
|
||||||
let mut client = networks_client::NetworksClient::new(daemon_client);
|
let mut client = networks_client::NetworksClient::new(daemon_client);
|
||||||
client
|
let _ = client
|
||||||
.network_reorder(burrow_rpc::NetworkReorderRequest {
|
.network_reorder(burrow_rpc::NetworkReorderRequest {
|
||||||
id: self.id,
|
id: self.id,
|
||||||
index: self.index as i32 - 1,
|
index: self.index as i32 - 1,
|
||||||
})
|
})
|
||||||
.await
|
.await;
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -117,13 +115,12 @@ impl AsyncComponent for NetworkCard {
|
||||||
if self.index + 1 < self.index_max {
|
if self.index + 1 < self.index_max {
|
||||||
if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() {
|
if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() {
|
||||||
let mut client = networks_client::NetworksClient::new(daemon_client);
|
let mut client = networks_client::NetworksClient::new(daemon_client);
|
||||||
client
|
let _ = client
|
||||||
.network_reorder(burrow_rpc::NetworkReorderRequest {
|
.network_reorder(burrow_rpc::NetworkReorderRequest {
|
||||||
id: self.id,
|
id: self.id,
|
||||||
index: self.index as i32 + 1,
|
index: self.index as i32 + 1,
|
||||||
})
|
})
|
||||||
.await
|
.await;
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ pub struct Networks {
|
||||||
daemon_client: Arc<Mutex<Option<Channel>>>,
|
daemon_client: Arc<Mutex<Option<Channel>>>,
|
||||||
network_cards: Vec<AsyncController<NetworkCard>>,
|
network_cards: Vec<AsyncController<NetworkCard>>,
|
||||||
networks_list_box: gtk::ListBox,
|
networks_list_box: gtk::ListBox,
|
||||||
|
|
||||||
|
_network_state_worker: WorkerController<AsyncNetworkStateHandler>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NetworksInit {
|
pub struct NetworksInit {
|
||||||
|
|
@ -94,6 +96,10 @@ impl AsyncComponent for Networks {
|
||||||
daemon_client: init.daemon_client,
|
daemon_client: init.daemon_client,
|
||||||
network_cards,
|
network_cards,
|
||||||
networks_list_box: widgets.networks.clone(),
|
networks_list_box: widgets.networks.clone(),
|
||||||
|
|
||||||
|
_network_state_worker: AsyncNetworkStateHandler::builder()
|
||||||
|
.detach_worker(())
|
||||||
|
.forward(sender.input_sender(), |msg| msg),
|
||||||
};
|
};
|
||||||
|
|
||||||
AsyncComponentParts { model, widgets }
|
AsyncComponentParts { model, widgets }
|
||||||
|
|
@ -132,7 +138,7 @@ impl AsyncComponent for Networks {
|
||||||
NetworksMsg::NetworkAdd => {
|
NetworksMsg::NetworkAdd => {
|
||||||
if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() {
|
if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() {
|
||||||
let mut client = networks_client::NetworksClient::new(daemon_client);
|
let mut client = networks_client::NetworksClient::new(daemon_client);
|
||||||
client.network_add(burrow_rpc::Empty {}).await.unwrap();
|
let _ = client.network_add(burrow_rpc::Empty {}).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
@ -147,7 +153,8 @@ impl Worker for AsyncNetworkStateHandler {
|
||||||
type Input = ();
|
type Input = ();
|
||||||
type Output = NetworksMsg;
|
type Output = NetworksMsg;
|
||||||
|
|
||||||
fn init(_: Self::Init, _sender: ComponentSender<Self>) -> Self {
|
fn init(_: Self::Init, sender: ComponentSender<Self>) -> Self {
|
||||||
|
sender.input(());
|
||||||
Self
|
Self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,6 @@ const RECONNECT_POLL_TIME: Duration = Duration::from_secs(3);
|
||||||
pub struct Switch {
|
pub struct Switch {
|
||||||
daemon_client: Arc<Mutex<Option<Channel>>>,
|
daemon_client: Arc<Mutex<Option<Channel>>>,
|
||||||
switch: gtk::Switch,
|
switch: gtk::Switch,
|
||||||
switch_screen: gtk::Box,
|
|
||||||
disconnected_banner: adw::Banner,
|
|
||||||
|
|
||||||
_tunnel_state_worker: WorkerController<AsyncTunnelStateHandler>,
|
_tunnel_state_worker: WorkerController<AsyncTunnelStateHandler>,
|
||||||
}
|
}
|
||||||
|
|
@ -19,8 +17,6 @@ pub struct SwitchInit {
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum SwitchMsg {
|
pub enum SwitchMsg {
|
||||||
None,
|
None,
|
||||||
DaemonReconnect,
|
|
||||||
DaemonDisconnect,
|
|
||||||
Start,
|
Start,
|
||||||
Stop,
|
Stop,
|
||||||
SwitchSetStart,
|
SwitchSetStart,
|
||||||
|
|
@ -51,7 +47,6 @@ impl AsyncComponent for Switch {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
#[name(switch_screen)]
|
|
||||||
gtk::Box {
|
gtk::Box {
|
||||||
set_orientation: gtk::Orientation::Vertical,
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
set_spacing: 10,
|
set_spacing: 10,
|
||||||
|
|
@ -80,37 +75,12 @@ impl AsyncComponent for Switch {
|
||||||
root: Self::Root,
|
root: Self::Root,
|
||||||
sender: AsyncComponentSender<Self>,
|
sender: AsyncComponentSender<Self>,
|
||||||
) -> AsyncComponentParts<Self> {
|
) -> AsyncComponentParts<Self> {
|
||||||
let mut initial_daemon_server_down = false;
|
|
||||||
|
|
||||||
if let Some(daemon_client) = init.daemon_client.lock().await.as_mut() {
|
|
||||||
let mut client = tunnel_client::TunnelClient::new(daemon_client);
|
|
||||||
if client
|
|
||||||
.tunnel_status(burrow_rpc::Empty {})
|
|
||||||
.await
|
|
||||||
.as_mut()
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
initial_daemon_server_down = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
initial_daemon_server_down = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let switch_sender = sender.clone();
|
let switch_sender = sender.clone();
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
|
|
||||||
if initial_daemon_server_down {
|
|
||||||
*init.daemon_client.lock().await = None;
|
|
||||||
widgets.switch.set_active(false);
|
|
||||||
widgets.switch_screen.set_sensitive(false);
|
|
||||||
widgets.setup_banner.set_revealed(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
let model = Switch {
|
let model = Switch {
|
||||||
daemon_client: init.daemon_client,
|
daemon_client: init.daemon_client,
|
||||||
switch: widgets.switch.clone(),
|
switch: widgets.switch.clone(),
|
||||||
switch_screen: widgets.switch_screen.clone(),
|
|
||||||
disconnected_banner: widgets.setup_banner.clone(),
|
|
||||||
_tunnel_state_worker: AsyncTunnelStateHandler::builder()
|
_tunnel_state_worker: AsyncTunnelStateHandler::builder()
|
||||||
.detach_worker(())
|
.detach_worker(())
|
||||||
.forward(sender.input_sender(), |_| SwitchMsg::None),
|
.forward(sender.input_sender(), |_| SwitchMsg::None),
|
||||||
|
|
@ -127,20 +97,16 @@ impl AsyncComponent for Switch {
|
||||||
_: AsyncComponentSender<Self>,
|
_: AsyncComponentSender<Self>,
|
||||||
_root: &Self::Root,
|
_root: &Self::Root,
|
||||||
) {
|
) {
|
||||||
let mut disconnected_daemon_client = false;
|
|
||||||
|
|
||||||
if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() {
|
if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() {
|
||||||
let mut client = tunnel_client::TunnelClient::new(daemon_client);
|
let mut client = tunnel_client::TunnelClient::new(daemon_client);
|
||||||
match msg {
|
match msg {
|
||||||
Self::Input::Start => {
|
Self::Input::Start => {
|
||||||
if let Err(_e) = client.tunnel_start(burrow_rpc::Empty {}).await {
|
// TODO: Figure out best way for error handling.
|
||||||
disconnected_daemon_client = true;
|
let _ = client.tunnel_start(burrow_rpc::Empty {}).await;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Self::Input::Stop => {
|
Self::Input::Stop => {
|
||||||
if let Err(_e) = client.tunnel_stop(burrow_rpc::Empty {}).await {
|
// TODO: Figure out best way for error handling.
|
||||||
disconnected_daemon_client = true;
|
let _ = client.tunnel_stop(burrow_rpc::Empty {}).await;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Self::Input::SwitchSetStart => {
|
Self::Input::SwitchSetStart => {
|
||||||
self.switch.set_active(true);
|
self.switch.set_active(true);
|
||||||
|
|
@ -150,19 +116,6 @@ impl AsyncComponent for Switch {
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
disconnected_daemon_client = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if msg == Self::Input::DaemonReconnect {
|
|
||||||
self.disconnected_banner.set_revealed(false);
|
|
||||||
self.switch_screen.set_sensitive(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if disconnected_daemon_client || msg == Self::Input::DaemonDisconnect {
|
|
||||||
*self.daemon_client.lock().await = None;
|
|
||||||
self.switch_screen.set_sensitive(false);
|
|
||||||
self.disconnected_banner.set_revealed(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -174,7 +127,8 @@ impl Worker for AsyncTunnelStateHandler {
|
||||||
type Input = ();
|
type Input = ();
|
||||||
type Output = SwitchMsg;
|
type Output = SwitchMsg;
|
||||||
|
|
||||||
fn init(_: Self::Init, _sender: ComponentSender<Self>) -> Self {
|
fn init(_: Self::Init, sender: ComponentSender<Self>) -> Self {
|
||||||
|
sender.input(());
|
||||||
Self
|
Self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub struct MainScreen {
|
pub struct MainScreen {
|
||||||
switch: AsyncController<main::Switch>,
|
_switch: AsyncController<main::Switch>,
|
||||||
networks: AsyncController<main::Networks>,
|
_networks: AsyncController<main::Networks>,
|
||||||
|
content_box: gtk::Box,
|
||||||
|
daemon_status_banner: adw::Banner,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MainScreenInit {
|
pub struct MainScreenInit {
|
||||||
|
|
@ -29,17 +31,17 @@ impl AsyncComponent for MainScreen {
|
||||||
set_valign: Align::Fill,
|
set_valign: Align::Fill,
|
||||||
set_valign: Align::Center,
|
set_valign: Align::Center,
|
||||||
|
|
||||||
// gtk::Box {
|
gtk::Box {
|
||||||
// set_orientation: gtk::Orientation::Vertical,
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
// set_spacing: 5,
|
set_spacing: 5,
|
||||||
// set_margin_all: 5,
|
set_margin_all: 5,
|
||||||
// set_valign: Align::Start,
|
set_valign: Align::Start,
|
||||||
|
|
||||||
// #[name(setup_banner)]
|
#[name(daemon_status_banner)]
|
||||||
// adw::Banner {
|
adw::Banner {
|
||||||
// set_title: "Burrow is not running!",
|
set_title: "Burrow is not running!",
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
|
|
||||||
gtk::Box {
|
gtk::Box {
|
||||||
set_orientation: gtk::Orientation::Vertical,
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
|
@ -86,7 +88,12 @@ impl AsyncComponent for MainScreen {
|
||||||
widgets.content.append(networks.widget());
|
widgets.content.append(networks.widget());
|
||||||
widgets.content.append(switch.widget());
|
widgets.content.append(switch.widget());
|
||||||
|
|
||||||
let model = MainScreen { switch, networks };
|
let model = MainScreen {
|
||||||
|
_switch: switch,
|
||||||
|
_networks: networks,
|
||||||
|
content_box: widgets.content.clone(),
|
||||||
|
daemon_status_banner: widgets.daemon_status_banner.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
AsyncComponentParts { model, widgets }
|
AsyncComponentParts { model, widgets }
|
||||||
}
|
}
|
||||||
|
|
@ -99,10 +106,12 @@ impl AsyncComponent for MainScreen {
|
||||||
) {
|
) {
|
||||||
match msg {
|
match msg {
|
||||||
MainScreenMsg::DaemonDisconnect => {
|
MainScreenMsg::DaemonDisconnect => {
|
||||||
self.switch.emit(main::SwitchMsg::DaemonDisconnect);
|
self.daemon_status_banner.set_revealed(true);
|
||||||
|
self.content_box.set_sensitive(false);
|
||||||
}
|
}
|
||||||
MainScreenMsg::DaemonReconnect => {
|
MainScreenMsg::DaemonReconnect => {
|
||||||
self.switch.emit(main::SwitchMsg::DaemonReconnect);
|
self.daemon_status_banner.set_revealed(false);
|
||||||
|
self.content_box.set_sensitive(true);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,199 +0,0 @@
|
||||||
use super::*;
|
|
||||||
use std::{
|
|
||||||
thread::{self, JoinHandle},
|
|
||||||
time::Duration,
|
|
||||||
};
|
|
||||||
|
|
||||||
const RECONNECT_POLL_TIME: Duration = Duration::from_secs(3);
|
|
||||||
|
|
||||||
pub struct SwitchScreen {
|
|
||||||
daemon_client: Arc<Mutex<Option<Channel>>>,
|
|
||||||
switch: gtk::Switch,
|
|
||||||
switch_screen: gtk::Box,
|
|
||||||
disconnected_banner: adw::Banner,
|
|
||||||
tunnel_state_worker: JoinHandle<()>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SwitchScreenInit {
|
|
||||||
pub daemon_client: Arc<Mutex<Option<Channel>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
|
||||||
pub enum SwitchScreenMsg {
|
|
||||||
DaemonReconnect,
|
|
||||||
DaemonDisconnect,
|
|
||||||
Start,
|
|
||||||
Stop,
|
|
||||||
TunnelStateStopped,
|
|
||||||
TunnelStateRunning,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[relm4::component(pub, async)]
|
|
||||||
impl AsyncComponent for SwitchScreen {
|
|
||||||
type Init = SwitchScreenInit;
|
|
||||||
type Input = SwitchScreenMsg;
|
|
||||||
type Output = ();
|
|
||||||
type CommandOutput = SwitchScreenMsg;
|
|
||||||
|
|
||||||
view! {
|
|
||||||
gtk::Box {
|
|
||||||
set_orientation: gtk::Orientation::Vertical,
|
|
||||||
set_valign: Align::Fill,
|
|
||||||
|
|
||||||
gtk::Box {
|
|
||||||
set_orientation: gtk::Orientation::Vertical,
|
|
||||||
set_spacing: 5,
|
|
||||||
set_margin_all: 5,
|
|
||||||
set_valign: Align::Start,
|
|
||||||
|
|
||||||
#[name(setup_banner)]
|
|
||||||
adw::Banner {
|
|
||||||
set_title: "Burrow is not running!",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
#[name(switch_screen)]
|
|
||||||
gtk::Box {
|
|
||||||
set_orientation: gtk::Orientation::Vertical,
|
|
||||||
set_spacing: 10,
|
|
||||||
set_margin_all: 5,
|
|
||||||
set_valign: Align::Center,
|
|
||||||
set_vexpand: true,
|
|
||||||
|
|
||||||
gtk::Label {
|
|
||||||
set_label: "Burrow Switch",
|
|
||||||
},
|
|
||||||
|
|
||||||
#[name(switch)]
|
|
||||||
gtk::Switch {
|
|
||||||
set_halign: Align::Center,
|
|
||||||
set_hexpand: false,
|
|
||||||
set_vexpand: false,
|
|
||||||
connect_active_notify => move |switch|
|
|
||||||
switch_sender.input(if switch.is_active() { SwitchScreenMsg::Start } else { SwitchScreenMsg::Stop })
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn init(
|
|
||||||
init: Self::Init,
|
|
||||||
root: Self::Root,
|
|
||||||
sender: AsyncComponentSender<Self>,
|
|
||||||
) -> AsyncComponentParts<Self> {
|
|
||||||
let mut initial_daemon_server_down = false;
|
|
||||||
|
|
||||||
if let Some(daemon_client) = init.daemon_client.lock().await.as_mut() {
|
|
||||||
let mut client = tunnel_client::TunnelClient::new(daemon_client);
|
|
||||||
if client
|
|
||||||
.tunnel_status(burrow_rpc::Empty {})
|
|
||||||
.await
|
|
||||||
.as_mut()
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
initial_daemon_server_down = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
initial_daemon_server_down = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let switch_sender = sender.clone();
|
|
||||||
let tunnel_state_sender = sender.clone();
|
|
||||||
let widgets = view_output!();
|
|
||||||
|
|
||||||
if initial_daemon_server_down {
|
|
||||||
*init.daemon_client.lock().await = None;
|
|
||||||
widgets.switch.set_active(false);
|
|
||||||
widgets.switch_screen.set_sensitive(false);
|
|
||||||
widgets.setup_banner.set_revealed(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
let model = SwitchScreen {
|
|
||||||
daemon_client: init.daemon_client,
|
|
||||||
switch: widgets.switch.clone(),
|
|
||||||
switch_screen: widgets.switch_screen.clone(),
|
|
||||||
disconnected_banner: widgets.setup_banner.clone(),
|
|
||||||
tunnel_state_worker: thread::spawn(move || {
|
|
||||||
tunnel_state_worker(tunnel_state_sender);
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
widgets.switch.set_active(false);
|
|
||||||
|
|
||||||
AsyncComponentParts { model, widgets }
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn update(
|
|
||||||
&mut self,
|
|
||||||
msg: Self::Input,
|
|
||||||
_: AsyncComponentSender<Self>,
|
|
||||||
_root: &Self::Root,
|
|
||||||
) {
|
|
||||||
let mut disconnected_daemon_client = false;
|
|
||||||
|
|
||||||
if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() {
|
|
||||||
let mut client = tunnel_client::TunnelClient::new(daemon_client);
|
|
||||||
match msg {
|
|
||||||
Self::Input::Start => {
|
|
||||||
if let Err(e) = client.tunnel_start(burrow_rpc::Empty {}).await {
|
|
||||||
disconnected_daemon_client = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Self::Input::Stop => {
|
|
||||||
if let Err(e) = client.tunnel_stop(burrow_rpc::Empty {}).await {
|
|
||||||
disconnected_daemon_client = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Self::Input::TunnelStateStopped => {
|
|
||||||
self.switch.set_active(false);
|
|
||||||
}
|
|
||||||
Self::Input::TunnelStateRunning => {
|
|
||||||
self.switch.set_active(true);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
disconnected_daemon_client = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if msg == Self::Input::DaemonReconnect {
|
|
||||||
self.disconnected_banner.set_revealed(false);
|
|
||||||
self.switch_screen.set_sensitive(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if disconnected_daemon_client || msg == Self::Input::DaemonDisconnect {
|
|
||||||
*self.daemon_client.lock().await = None;
|
|
||||||
self.switch_screen.set_sensitive(false);
|
|
||||||
self.disconnected_banner.set_revealed(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn tunnel_state_worker(sender: AsyncComponentSender<SwitchScreen>) {
|
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
|
||||||
let task = rt.spawn(async move {
|
|
||||||
loop {
|
|
||||||
let sender = sender.input_sender();
|
|
||||||
let conn = daemon::daemon_connect().await;
|
|
||||||
if let Ok(conn) = conn {
|
|
||||||
let mut client = tunnel_client::TunnelClient::new(conn);
|
|
||||||
if let Ok(mut res) = client.tunnel_status(burrow_rpc::Empty {}).await {
|
|
||||||
let stream = res.get_mut();
|
|
||||||
while let Ok(Some(msg)) = stream.message().await {
|
|
||||||
match msg.state() {
|
|
||||||
burrow_rpc::State::Stopped => {
|
|
||||||
sender.send(SwitchScreenMsg::TunnelStateStopped)
|
|
||||||
}
|
|
||||||
burrow_rpc::State::Running => {
|
|
||||||
sender.send(SwitchScreenMsg::TunnelStateRunning)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tokio::time::sleep(RECONNECT_POLL_TIME).await;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
rt.block_on(task).unwrap();
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue