mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-09-18 12:46:58 +02:00
refactor(networkmanager): use inner client with static lifetime, make its functions methods
This commit is contained in:
parent
5385c7e705
commit
13c2520c76
1 changed files with 150 additions and 142 deletions
|
@ -18,36 +18,54 @@ pub mod event;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
controller_sender: broadcast::Sender<ClientToModuleEvent>,
|
inner: &'static ClientInner,
|
||||||
sender: broadcast::Sender<ModuleToClientEvent>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
fn new() -> Result<Client> {
|
fn new() -> Client {
|
||||||
let (controller_sender, _) = broadcast::channel(64);
|
let inner = Box::leak(Box::new(ClientInner::new()));
|
||||||
let (sender, _) = broadcast::channel(8);
|
Client { inner }
|
||||||
Ok(Client {
|
|
||||||
controller_sender,
|
|
||||||
sender,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self) -> Result<()> {
|
fn run(&self) -> Result<()> {
|
||||||
|
self.inner.run()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn subscribe(&self) -> broadcast::Receiver<ClientToModuleEvent> {
|
||||||
|
self.inner.subscribe()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_sender(&self) -> broadcast::Sender<ModuleToClientEvent> {
|
||||||
|
self.inner.get_sender()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct ClientInner {
|
||||||
|
controller_sender: broadcast::Sender<ClientToModuleEvent>,
|
||||||
|
sender: broadcast::Sender<ModuleToClientEvent>,
|
||||||
|
devices: RwLock<HashSet<ObjectPath<'static>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClientInner {
|
||||||
|
fn new() -> ClientInner {
|
||||||
|
let (controller_sender, _) = broadcast::channel(64);
|
||||||
|
let (sender, _) = broadcast::channel(8);
|
||||||
|
let devices = RwLock::new(HashSet::<ObjectPath>::new());
|
||||||
|
ClientInner {
|
||||||
|
controller_sender,
|
||||||
|
sender,
|
||||||
|
devices,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(&'static self) -> Result<()> {
|
||||||
debug!("Client running");
|
debug!("Client running");
|
||||||
|
|
||||||
let devices = Arc::new(RwLock::new(HashSet::<ObjectPath>::new()));
|
spawn(self.watch_devices_list());
|
||||||
|
|
||||||
spawn(watch_devices_list(
|
|
||||||
devices.clone(),
|
|
||||||
self.controller_sender.clone(),
|
|
||||||
));
|
|
||||||
|
|
||||||
let receiver = self.sender.subscribe();
|
let receiver = self.sender.subscribe();
|
||||||
spawn(handle_received_events(
|
spawn(self.handle_received_events(receiver));
|
||||||
receiver,
|
|
||||||
devices.clone(),
|
|
||||||
self.controller_sender.clone(),
|
|
||||||
));
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -59,18 +77,8 @@ impl Client {
|
||||||
pub fn get_sender(&self) -> broadcast::Sender<ModuleToClientEvent> {
|
pub fn get_sender(&self) -> broadcast::Sender<ModuleToClientEvent> {
|
||||||
self.sender.clone()
|
self.sender.clone()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_client() -> ClientResult<Client> {
|
async fn watch_devices_list(&'static self) -> Result<()> {
|
||||||
let client = Arc::new(Client::new()?);
|
|
||||||
client.run()?;
|
|
||||||
Ok(client)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn watch_devices_list(
|
|
||||||
devices: Arc<RwLock<HashSet<ObjectPath<'_>>>>,
|
|
||||||
controller_sender: broadcast::Sender<ClientToModuleEvent>,
|
|
||||||
) -> Result<()> {
|
|
||||||
debug!("D-Bus devices list watcher starting");
|
debug!("D-Bus devices list watcher starting");
|
||||||
|
|
||||||
let dbus_connection = Connection::system().await?;
|
let dbus_connection = Connection::system().await?;
|
||||||
|
@ -87,17 +95,14 @@ async fn watch_devices_list(
|
||||||
.collect::<HashSet<_>>();
|
.collect::<HashSet<_>>();
|
||||||
|
|
||||||
// Atomic read-then-write of `devices`
|
// Atomic read-then-write of `devices`
|
||||||
let mut devices_locked = devices.write().await;
|
let mut devices_locked = self.devices.write().await;
|
||||||
let devices_snapshot = devices_locked.clone();
|
let devices_snapshot = devices_locked.clone();
|
||||||
(*devices_locked).clone_from(&new_devices);
|
(*devices_locked).clone_from(&new_devices);
|
||||||
drop(devices_locked);
|
drop(devices_locked);
|
||||||
|
|
||||||
let added_devices = new_devices.difference(&devices_snapshot);
|
let added_devices = new_devices.difference(&devices_snapshot);
|
||||||
for added_device in added_devices {
|
for added_device in added_devices {
|
||||||
spawn(watch_device(
|
spawn(self.watch_device(added_device.to_owned()));
|
||||||
added_device.to_owned(),
|
|
||||||
controller_sender.clone(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let _removed_devices = devices_snapshot.difference(&new_devices);
|
let _removed_devices = devices_snapshot.difference(&new_devices);
|
||||||
|
@ -106,13 +111,12 @@ async fn watch_devices_list(
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_received_events(
|
async fn handle_received_events(
|
||||||
|
&'static self,
|
||||||
mut receiver: broadcast::Receiver<ModuleToClientEvent>,
|
mut receiver: broadcast::Receiver<ModuleToClientEvent>,
|
||||||
devices: Arc<RwLock<HashSet<ObjectPath<'_>>>>,
|
) -> Result<()> {
|
||||||
controller_sender: broadcast::Sender<ClientToModuleEvent>,
|
|
||||||
) -> Result<()> {
|
|
||||||
while let Result::Ok(event) = receiver.recv().await {
|
while let Result::Ok(event) = receiver.recv().await {
|
||||||
match event {
|
match event {
|
||||||
ModuleToClientEvent::NewController => {
|
ModuleToClientEvent::NewController => {
|
||||||
|
@ -121,7 +125,7 @@ async fn handle_received_events(
|
||||||
let dbus_connection = Connection::system().await?;
|
let dbus_connection = Connection::system().await?;
|
||||||
|
|
||||||
// We create a local clone here to avoid holding the lock for too long
|
// We create a local clone here to avoid holding the lock for too long
|
||||||
let devices_snapshot = devices.read().await.clone();
|
let devices_snapshot = self.devices.read().await.clone();
|
||||||
|
|
||||||
for device_path in devices_snapshot {
|
for device_path in devices_snapshot {
|
||||||
let device = DeviceDbusProxy::new(&dbus_connection, device_path).await?;
|
let device = DeviceDbusProxy::new(&dbus_connection, device_path).await?;
|
||||||
|
@ -129,7 +133,8 @@ async fn handle_received_events(
|
||||||
let interface = device.interface().await?.to_string();
|
let interface = device.interface().await?.to_string();
|
||||||
let r#type = device.device_type().await?;
|
let r#type = device.device_type().await?;
|
||||||
let new_state = device.state().await?;
|
let new_state = device.state().await?;
|
||||||
controller_sender.send(ClientToModuleEvent::DeviceChanged {
|
self.controller_sender
|
||||||
|
.send(ClientToModuleEvent::DeviceChanged {
|
||||||
interface,
|
interface,
|
||||||
r#type,
|
r#type,
|
||||||
new_state,
|
new_state,
|
||||||
|
@ -140,24 +145,18 @@ async fn handle_received_events(
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn watch_device(
|
async fn watch_device(&'static self, path: ObjectPath<'static>) -> Result<()> {
|
||||||
path: ObjectPath<'_>,
|
|
||||||
controller_sender: broadcast::Sender<ClientToModuleEvent>,
|
|
||||||
) -> Result<()> {
|
|
||||||
let dbus_connection = Connection::system().await?;
|
let dbus_connection = Connection::system().await?;
|
||||||
let device = DeviceDbusProxy::new(&dbus_connection, path.to_owned()).await?;
|
let device = DeviceDbusProxy::new(&dbus_connection, path).await?;
|
||||||
|
|
||||||
spawn(watch_device_state(device, controller_sender));
|
spawn(self.watch_device_state(device));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn watch_device_state(
|
async fn watch_device_state(&'static self, device: DeviceDbusProxy<'_>) -> Result<()> {
|
||||||
device: DeviceDbusProxy<'_>,
|
|
||||||
controller_sender: broadcast::Sender<ClientToModuleEvent>,
|
|
||||||
) -> Result<()> {
|
|
||||||
let path = device.inner().path();
|
let path = device.inner().path();
|
||||||
|
|
||||||
debug!("D-Bus device state watcher for {} starting", path);
|
debug!("D-Bus device state watcher for {} starting", path);
|
||||||
|
@ -167,7 +166,8 @@ async fn watch_device_state(
|
||||||
|
|
||||||
// Send an event communicating the initial state
|
// Send an event communicating the initial state
|
||||||
let new_state = device.state().await?;
|
let new_state = device.state().await?;
|
||||||
controller_sender.send(ClientToModuleEvent::DeviceChanged {
|
self.controller_sender
|
||||||
|
.send(ClientToModuleEvent::DeviceChanged {
|
||||||
interface: interface.to_string(),
|
interface: interface.to_string(),
|
||||||
r#type: r#type.clone(),
|
r#type: r#type.clone(),
|
||||||
new_state,
|
new_state,
|
||||||
|
@ -176,7 +176,8 @@ async fn watch_device_state(
|
||||||
let mut state_changes = device.receive_state_changed().await;
|
let mut state_changes = device.receive_state_changed().await;
|
||||||
while let Some(state_change) = state_changes.next().await {
|
while let Some(state_change) = state_changes.next().await {
|
||||||
let new_state = state_change.get().await?;
|
let new_state = state_change.get().await?;
|
||||||
controller_sender.send(ClientToModuleEvent::DeviceChanged {
|
self.controller_sender
|
||||||
|
.send(ClientToModuleEvent::DeviceChanged {
|
||||||
interface: interface.to_string(),
|
interface: interface.to_string(),
|
||||||
r#type: r#type.clone(),
|
r#type: r#type.clone(),
|
||||||
new_state,
|
new_state,
|
||||||
|
@ -186,6 +187,13 @@ async fn watch_device_state(
|
||||||
debug!("D-Bus device state watcher for {} ended", path);
|
debug!("D-Bus device state watcher for {} ended", path);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_client() -> ClientResult<Client> {
|
||||||
|
let client = Arc::new(Client::new());
|
||||||
|
client.run()?;
|
||||||
|
Ok(client)
|
||||||
}
|
}
|
||||||
|
|
||||||
register_fallible_client!(Client, network_manager);
|
register_fallible_client!(Client, network_manager);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue