Private
Public Access
1
0

daemon: start working on events. notes:

Probably need to make the locking mechanism more granular. Only lock the
database during db writes, see if we can do multiple readers and a
single writer. Otherwise, the daemon will not be able to service
requests while an event is being handled, which is not good.
This commit is contained in:
2025-04-25 21:42:29 -07:00
parent 82192ffbe5
commit ef74df9f28
7 changed files with 90 additions and 46 deletions

View File

@@ -1,63 +1,69 @@
use dbus::arg;
use dbus_tree::MethodErr;
use std::sync::{Arc, Mutex, MutexGuard};
use std::sync::Arc;
use tokio::sync::{Mutex, MutexGuard};
use std::future::Future;
use std::thread;
use std::sync::mpsc;
use futures_util::future::FutureExt;
use crate::daemon::Daemon;
use crate::daemon::{Daemon, Event};
use crate::dbus::interface::NetBuzzertKordophoneRepository as DbusRepository;
use crate::dbus::interface::NetBuzzertKordophoneSettings as DbusSettings;
#[derive(Clone)]
pub struct ServerImpl {
daemon: Arc<Mutex<Daemon>>,
event_sender: mpsc::Sender<Event>,
}
impl ServerImpl {
pub fn new(daemon: Arc<Mutex<Daemon>>) -> Self {
Self { daemon }
pub fn new(daemon: Arc<Mutex<Daemon>>, event_sender: mpsc::Sender<Event>) -> Self {
Self { daemon, event_sender }
}
pub fn get_daemon(&self) -> Result<MutexGuard<'_, Daemon>, MethodErr> {
self.daemon.lock().map_err(|_| MethodErr::failed("Failed to lock daemon"))
pub async fn get_daemon(&self) -> MutexGuard<'_, Daemon> {
self.daemon.lock().await // .map_err(|_| MethodErr::failed("Failed to lock daemon"))
}
pub fn daemon_then<F, T>(&self, f: F) -> Result<T, MethodErr>
where F: FnOnce(MutexGuard<'_, Daemon>) -> T + Send,
T: Send,
{
run_sync_future(self.get_daemon().then(|daemon| async move {
f(daemon)
}))
}
}
impl DbusRepository for ServerImpl {
fn get_version(&mut self) -> Result<String, MethodErr> {
let daemon = self.get_daemon()?;
Ok(daemon.version.clone())
self.daemon_then(|daemon| daemon.version.clone())
}
fn get_conversations(&mut self) -> Result<Vec<arg::PropMap>, dbus::MethodErr> {
// Get a repository instance and use it to fetch conversations
let mut daemon = self.get_daemon()?;
let conversations = daemon.get_conversations();
// Convert conversations to DBus property maps
let result = conversations.into_iter().map(|conv| {
let mut map = arg::PropMap::new();
map.insert("guid".into(), arg::Variant(Box::new(conv.guid)));
map.insert("display_name".into(), arg::Variant(Box::new(conv.display_name.unwrap_or_default())));
map.insert("unread_count".into(), arg::Variant(Box::new(conv.unread_count as i32)));
map
}).collect();
Ok(result)
self.daemon_then(|mut daemon| {
let conversations = daemon.get_conversations();
// Convert conversations to DBus property maps
let result = conversations.into_iter().map(|conv| {
let mut map = arg::PropMap::new();
map.insert("guid".into(), arg::Variant(Box::new(conv.guid)));
map.insert("display_name".into(), arg::Variant(Box::new(conv.display_name.unwrap_or_default())));
map.insert("unread_count".into(), arg::Variant(Box::new(conv.unread_count as i32)));
map
}).collect();
Ok(result)
})?
}
fn sync_all_conversations(&mut self) -> Result<bool, dbus::MethodErr> {
let mut daemon = self.get_daemon()?;
fn sync_all_conversations(&mut self) -> Result<(), dbus::MethodErr> {
self.event_sender.send(Event::SyncAllConversations).unwrap_or_else(|e| {
log::error!("Error sending sync event: {}", e);
});
// TODO: We don't actually probably want to block here.
run_sync_future(daemon.sync_all_conversations())
.unwrap()
.map_err(|e| {
log::error!("Failed to sync conversations: {}", e);
MethodErr::failed(&format!("Failed to sync conversations: {}", e))
})?;
Ok(true)
Ok(())
}
}