xmpp: make Agent.config accessible only via getter

It may not matter much for the moment as this struct shouldn't change
very much during the life of the client, but this prevents the lock from
being held too long.

Signed-off-by: pep <pep@bouah.net>
This commit is contained in:
pep 2025-11-16 22:37:54 +01:00
commit e22daa91f1
7 changed files with 17 additions and 12 deletions

View file

@ -24,7 +24,7 @@ use tokio_xmpp::{Stanza, stanzastream::StanzaToken};
pub struct Agent { pub struct Agent {
pub(crate) client: TokioXmppClient, pub(crate) client: TokioXmppClient,
pub(crate) config: Arc<RwLock<Config>>, config: Arc<RwLock<Config>>,
pub(crate) disco: DiscoInfoResult, pub(crate) disco: DiscoInfoResult,
pub(crate) uploads: Vec<(String, Jid, PathBuf)>, pub(crate) uploads: Vec<(String, Jid, PathBuf)>,
pub(crate) awaiting_disco_bookmarks_type: bool, pub(crate) awaiting_disco_bookmarks_type: bool,
@ -55,6 +55,10 @@ impl Agent {
*c = config; *c = config;
} }
pub async fn get_config(&self) -> Config {
self.config.read().await.clone()
}
pub async fn disconnect(self) -> Result<(), Error> { pub async fn disconnect(self) -> Result<(), Error> {
self.client.send_end().await self.client.send_end().await
} }

View file

@ -8,7 +8,7 @@ use crate::RoomNick;
use core::str::FromStr; use core::str::FromStr;
/// [Disco](https://xmpp.org/registrar/disco-categories.html#client) identity type /// [Disco](https://xmpp.org/registrar/disco-categories.html#client) identity type
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum ClientType { pub enum ClientType {
Bot, Bot,
Pc, Pc,
@ -30,7 +30,7 @@ impl ToString for ClientType {
} }
/// Store Agent configuration. Differs from state which is generated at runtime /// Store Agent configuration. Differs from state which is generated at runtime
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct Config { pub struct Config {
/// Synchronize bookmarks based on autojoin flag. /// Synchronize bookmarks based on autojoin flag.
/// The client will join and leave based on the value of the `autojoin` flag on the (pubsub) /// The client will join and leave based on the value of the `autojoin` flag on the (pubsub)

View file

@ -21,7 +21,7 @@ pub async fn wait_for_events(agent: &mut Agent) -> Vec<Event> {
TokioXmppEvent::Online { resumed: false, .. } => { TokioXmppEvent::Online { resumed: false, .. } => {
let presence = presence::send::make_initial_presence( let presence = presence::send::make_initial_presence(
&agent.disco, &agent.disco,
&agent.config.read().await.website, &agent.get_config().await.website,
) )
.into(); .into();
let _ = agent.client.send_stanza(presence).await; let _ = agent.client.send_stanza(presence).await;

View file

@ -18,7 +18,7 @@ pub async fn handle_message_chat(
message: &mut Message, message: &mut Message,
time_info: StanzaTimeInfo, time_info: StanzaTimeInfo,
) { ) {
let config = agent.config.read().await; let config = agent.get_config().await;
let langs: Vec<&str> = config.lang.iter().map(String::as_str).collect(); let langs: Vec<&str> = config.lang.iter().map(String::as_str).collect();
let confirm = message.extract_valid_payload::<Confirm>(); let confirm = message.extract_valid_payload::<Confirm>();

View file

@ -18,7 +18,7 @@ pub async fn handle_message_group_chat(
message: &mut Message, message: &mut Message,
time_info: StanzaTimeInfo, time_info: StanzaTimeInfo,
) { ) {
let config = agent.config.read().await; let config = agent.get_config().await;
let langs: Vec<&str> = config.lang.iter().map(String::as_str).collect(); let langs: Vec<&str> = config.lang.iter().map(String::as_str).collect();
let mut found_subject = false; let mut found_subject = false;

View file

@ -78,8 +78,7 @@ pub async fn join_room<'a>(agent: &mut Agent, settings: JoinRoomSettings<'a>) {
let nick = if let Some(nick) = nick { let nick = if let Some(nick) = nick {
nick nick
} else { } else {
let config = agent.config.read().await; agent.get_config().await.default_nick
config.default_nick.clone()
}; };
let room_jid = room.with_resource(&nick); let room_jid = room.with_resource(&nick);

View file

@ -50,6 +50,7 @@ pub(crate) async fn handle_event(
events.extend(new_events); events.extend(new_events);
} }
ref node if node == ns::BOOKMARKS2 => { ref node if node == ns::BOOKMARKS2 => {
let config = agent.get_config().await;
// TODO: Check that our bare JID is the sender. // TODO: Check that our bare JID is the sender.
if let [item] = &published[..] { if let [item] = &published[..] {
let jid = BareJid::from_str(&item.id.clone().unwrap().0).unwrap(); let jid = BareJid::from_str(&item.id.clone().unwrap().0).unwrap();
@ -67,7 +68,7 @@ pub(crate) async fn handle_event(
}) })
.await; .await;
} else { } else {
if agent.config.read().await.bookmarks_autojoin { if config.bookmarks_autojoin {
// So maybe another client of ours left the room... let's leave it too // So maybe another client of ours left the room... let's leave it too
agent.leave_room(LeaveRoomSettings::new(jid)).await; agent.leave_room(LeaveRoomSettings::new(jid)).await;
} }
@ -77,7 +78,7 @@ pub(crate) async fn handle_event(
Err(err) => println!("not bookmark: {}", err), Err(err) => println!("not bookmark: {}", err),
} }
} else if let [item] = &retracted[..] { } else if let [item] = &retracted[..] {
if agent.config.read().await.bookmarks_autojoin { if config.bookmarks_autojoin {
let jid = BareJid::from_str(&item.0).unwrap(); let jid = BareJid::from_str(&item.0).unwrap();
agent.leave_room(LeaveRoomSettings::new(jid)).await; agent.leave_room(LeaveRoomSettings::new(jid)).await;
@ -125,6 +126,7 @@ pub(crate) async fn handle_iq_result(
events.extend(new_events); events.extend(new_events);
} }
ref node if node == ns::BOOKMARKS2 => { ref node if node == ns::BOOKMARKS2 => {
let config = agent.get_config().await;
// Keep track of the new added/removed rooms in the bookmarks2 list. // Keep track of the new added/removed rooms in the bookmarks2 list.
// The rooms we joined which are no longer in the list should be left ASAP. // The rooms we joined which are no longer in the list should be left ASAP.
let mut new_room_list: Vec<BareJid> = Vec::new(); let mut new_room_list: Vec<BareJid> = Vec::new();
@ -150,7 +152,7 @@ pub(crate) async fn handle_iq_result(
.await; .await;
} }
} else { } else {
if agent.config.read().await.bookmarks_autojoin { if config.bookmarks_autojoin {
// Leave the room that is no longer autojoin // Leave the room that is no longer autojoin
agent.leave_room(LeaveRoomSettings::new(jid)).await; agent.leave_room(LeaveRoomSettings::new(jid)).await;
} }
@ -162,7 +164,7 @@ pub(crate) async fn handle_iq_result(
} }
} }
if agent.config.read().await.bookmarks_autojoin { if config.bookmarks_autojoin {
// Now we leave the rooms that are no longer in the bookmarks // Now we leave the rooms that are no longer in the bookmarks
let mut rooms_to_leave: Vec<BareJid> = Vec::new(); let mut rooms_to_leave: Vec<BareJid> = Vec::new();
for (room, _nick) in &agent.rooms_joined { for (room, _nick) in &agent.rooms_joined {