Skip to content

Commit

Permalink
Use async_trait in the network Adapter trait
Browse files Browse the repository at this point in the history
  • Loading branch information
imobachgs committed Dec 29, 2023
1 parent 96036d4 commit d83b01e
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 38 deletions.
6 changes: 4 additions & 2 deletions rust/agama-dbus-server/src/network/adapter.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::network::NetworkState;
use async_trait::async_trait;
use std::error::Error;

/// A trait for the ability to read/write from/to a network service
#[async_trait]
pub trait Adapter {
fn read(&self) -> Result<NetworkState, Box<dyn Error>>;
fn write(&self, network: &NetworkState) -> Result<(), Box<dyn Error>>;
async fn read(&self) -> Result<NetworkState, Box<dyn Error>>;
async fn write(&self, network: &NetworkState) -> Result<(), Box<dyn Error>>;
}
54 changes: 23 additions & 31 deletions rust/agama-dbus-server/src/network/nm/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use crate::network::{
Adapter,
};
use agama_lib::error::ServiceError;
use async_trait::async_trait;
use log;
use tokio::{runtime::Handle, task};

/// An adapter for NetworkManager
pub struct NetworkManagerAdapter<'a> {
Expand All @@ -27,16 +27,12 @@ impl<'a> NetworkManagerAdapter<'a> {
}
}

#[async_trait]
impl<'a> Adapter for NetworkManagerAdapter<'a> {
fn read(&self) -> Result<NetworkState, Box<dyn std::error::Error>> {
task::block_in_place(|| {
Handle::current().block_on(async {
let devices = self.client.devices().await?;
let connections = self.client.connections().await?;

Ok(NetworkState::new(devices, connections))
})
})
async fn read(&self) -> Result<NetworkState, Box<dyn std::error::Error>> {
let devices = self.client.devices().await?;
let connections = self.client.connections().await?;
Ok(NetworkState::new(devices, connections))
}

/// Writes the connections to NetworkManager.
Expand All @@ -46,31 +42,27 @@ impl<'a> Adapter for NetworkManagerAdapter<'a> {
/// simpler approach.
///
/// * `network`: network model.
fn write(&self, network: &NetworkState) -> Result<(), Box<dyn std::error::Error>> {
async fn write(&self, network: &NetworkState) -> Result<(), Box<dyn std::error::Error>> {
// By now, traits do not support async functions. Using `task::block_on` allows
// to use 'await'.
task::block_in_place(|| {
Handle::current().block_on(async {
for conn in ordered_connections(network) {
if !Self::is_writable(conn) {
continue;
}
for conn in ordered_connections(network) {
if !Self::is_writable(conn) {
continue;
}

let result = if conn.is_removed() {
self.client.remove_connection(conn.uuid).await
} else {
let ctrl = conn
.controller
.and_then(|uuid| network.get_connection_by_uuid(uuid));
self.client.add_or_update_connection(conn, ctrl).await
};
let result = if conn.is_removed() {
self.client.remove_connection(conn.uuid).await
} else {
let ctrl = conn
.controller
.and_then(|uuid| network.get_connection_by_uuid(uuid));
self.client.add_or_update_connection(conn, ctrl).await
};

if let Err(e) = result {
log::error!("Could not process the connection {}: {}", conn.id, e);
}
}
})
});
if let Err(e) = result {
log::error!("Could not process the connection {}: {}", conn.id, e);
}
}
// FIXME: indicate which connections could not be written.
Ok(())
}
Expand Down
6 changes: 3 additions & 3 deletions rust/agama-dbus-server/src/network/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ impl<T: Adapter> NetworkSystem<T> {

/// Writes the network configuration.
pub async fn write(&mut self) -> Result<(), Box<dyn Error>> {
self.adapter.write(&self.state)?;
self.state = self.adapter.read()?;
self.adapter.write(&self.state).await?;
self.state = self.adapter.read().await?;
Ok(())
}

Expand All @@ -47,7 +47,7 @@ impl<T: Adapter> NetworkSystem<T> {

/// Populates the D-Bus tree with the known devices and connections.
pub async fn setup(&mut self) -> Result<(), Box<dyn Error>> {
self.state = self.adapter.read()?;
self.state = self.adapter.read().await?;
self.tree
.set_connections(&mut self.state.connections)
.await?;
Expand Down
9 changes: 7 additions & 2 deletions rust/agama-dbus-server/tests/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,24 @@ use agama_lib::network::{
types::DeviceType,
NetworkClient,
};
use async_trait::async_trait;
use cidr::IpInet;
use std::error::Error;
use tokio::test;

#[derive(Default)]
pub struct NetworkTestAdapter(network::NetworkState);

#[async_trait]
impl Adapter for NetworkTestAdapter {
fn read(&self) -> Result<network::NetworkState, Box<dyn std::error::Error>> {
async fn read(&self) -> Result<network::NetworkState, Box<dyn std::error::Error>> {
Ok(self.0.clone())
}

fn write(&self, _network: &network::NetworkState) -> Result<(), Box<dyn std::error::Error>> {
async fn write(
&self,
_network: &network::NetworkState,
) -> Result<(), Box<dyn std::error::Error>> {
unimplemented!("Not used in tests");
}
}
Expand Down

0 comments on commit d83b01e

Please sign in to comment.