🔊 Trace events from Matrix client callbacks to domain methods

This commit is contained in:
2024-05-21 12:22:04 +02:00
parent b5da0ee992
commit cd6506fb03
11 changed files with 405 additions and 163 deletions

View File

@@ -39,7 +39,8 @@ cfg-if = "1.0.0"
# Logging/tracing # Logging/tracing
tracing = "0.1.40" tracing = "0.1.40"
tracing-subscriber = "0.3.18" tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
tracing-forest = "0.1.6"
# SCSS -> CSS + usage in rust code # SCSS -> CSS + usage in rust code
turf = "0.8.0" turf = "0.8.0"

View File

@@ -1,7 +1,7 @@
use std::{cell::RefCell, collections::HashMap, rc::Rc}; use std::{cell::RefCell, collections::HashMap, rc::Rc};
use async_trait::async_trait; use async_trait::async_trait;
use tracing::error; use tracing::{error, instrument, trace};
use super::{ use super::{
common::PresenceState, common::PresenceState,
@@ -95,7 +95,10 @@ impl Account {
#[async_trait(?Send)] #[async_trait(?Send)]
impl AccountMessagingConsumerInterface for Account { impl AccountMessagingConsumerInterface for Account {
#[instrument(name = "Account", skip_all)]
async fn on_new_room(&self, room: Rc<Room>) -> Rc<dyn RoomMessagingConsumerInterface> { async fn on_new_room(&self, room: Rc<Room>) -> Rc<dyn RoomMessagingConsumerInterface> {
trace!("on_new_room");
let room_id = room.id().clone(); let room_id = room.id().clone();
self.by_id_rooms self.by_id_rooms
@@ -111,7 +114,10 @@ impl AccountMessagingConsumerInterface for Account {
room room
} }
#[instrument(name = "Account", skip_all)]
async fn on_new_space(&self, space: Rc<Space>) -> Rc<dyn SpaceMessagingConsumerInterface> { async fn on_new_space(&self, space: Rc<Space>) -> Rc<dyn SpaceMessagingConsumerInterface> {
trace!("on_new_space");
let space_id = space.id().clone(); let space_id = space.id().clone();
self.by_id_spaces self.by_id_spaces

View File

@@ -9,7 +9,7 @@ use async_trait::async_trait;
use futures::future::{join, join_all}; use futures::future::{join, join_all};
use matrix_sdk::ruma::OwnedRoomId; use matrix_sdk::ruma::OwnedRoomId;
use matrix_sdk::RoomState as MatrixRoomState; use matrix_sdk::RoomState as MatrixRoomState;
use tracing::{debug, error, trace}; use tracing::{debug, debug_span, error, instrument, trace};
use super::{ use super::{
common::{Avatar, UserId}, common::{Avatar, UserId},
@@ -18,7 +18,6 @@ use super::{
space::SpaceId, space::SpaceId,
store_interface::{RoomStoreConsumerInterface, RoomStoreProviderInterface}, store_interface::{RoomStoreConsumerInterface, RoomStoreProviderInterface},
}; };
use crate::infrastructure::services::mozaik_builder::create_mozaik; use crate::infrastructure::services::mozaik_builder::create_mozaik;
pub type RoomId = OwnedRoomId; pub type RoomId = OwnedRoomId;
@@ -150,6 +149,7 @@ impl Room {
self.state.map(|state| state == MatrixRoomState::Invited) self.state.map(|state| state == MatrixRoomState::Invited)
} }
#[instrument(name = "Room", skip_all)]
fn add_invitation(&self, invitation: Invitation) { fn add_invitation(&self, invitation: Invitation) {
self.members.borrow_mut().remove(&invitation.invitee_id); self.members.borrow_mut().remove(&invitation.invitee_id);
@@ -240,17 +240,44 @@ impl Room {
#[async_trait(?Send)] #[async_trait(?Send)]
impl RoomMessagingConsumerInterface for Room { impl RoomMessagingConsumerInterface for Room {
#[instrument(name = "Room", skip_all)]
async fn on_invitation(&self, invitation: Invitation) { async fn on_invitation(&self, invitation: Invitation) {
trace!("on_invitation");
let sender_id = invitation.sender_id.clone();
self.add_invitation(invitation); self.add_invitation(invitation);
if self.is_direct.unwrap_or(false) {
debug!("1to1 conversation, using the {} avatar", &sender_id);
if let Ok(avatar) = self.gen_room_avatar_with_members().await {
debug!("Avatar successfully generated");
self.avatar.borrow_mut().clone_from(&avatar);
if let Some(store) = self.store.borrow().as_ref() {
store.on_new_avatar(avatar);
} }
}
}
}
#[instrument(name = "Room", skip_all)]
async fn on_membership(&self, member: RoomMember) { async fn on_membership(&self, member: RoomMember) {
trace!("Room::on_membership({:?})", member); trace!("on_membership");
self.add_member(member);
} }
async fn on_new_topic(&self, topic: Option<String>) {
trace!("Room::on_new_topic({:?})", topic); #[instrument(name = "Room", skip_all)]
async fn on_new_topic(&self, _topic: Option<String>) {
trace!("on_new_topic");
} }
async fn on_new_name(&self, name: Option<String>) {
trace!("Room::on_new_name({:?})", name); #[instrument(name = "Room", skip_all)]
async fn on_new_name(&self, _name: Option<String>) {
trace!("on_new_name");
}
#[instrument(name = "Room", skip_all)]
async fn on_new_avatar(&self, avatar: Option<Avatar>) {
trace!("on_new_avatar");
} }
} }

View File

@@ -2,7 +2,7 @@ use std::{cell::RefCell, collections::HashSet, rc::Rc};
use async_trait::async_trait; use async_trait::async_trait;
use matrix_sdk::ruma::OwnedRoomId; use matrix_sdk::ruma::OwnedRoomId;
use tracing::error; use tracing::{instrument, trace};
use super::{ use super::{
common::Avatar, common::Avatar,
@@ -72,16 +72,21 @@ impl Space {
#[async_trait(?Send)] #[async_trait(?Send)]
impl SpaceMessagingConsumerInterface for Space { impl SpaceMessagingConsumerInterface for Space {
#[instrument(name = "Space", skip_all)]
async fn on_child(&self, room_id: RoomId) { async fn on_child(&self, room_id: RoomId) {
error!("Space::on_child({room_id})"); trace!("on_child");
self.children.borrow_mut().insert(room_id); self.children.borrow_mut().insert(room_id);
} }
#[instrument(name = "Space", skip_all)]
async fn on_new_topic(&self, topic: Option<String>) { async fn on_new_topic(&self, topic: Option<String>) {
error!("Space::on_new_topic({:?})", topic); trace!("on_new_topic");
*self.topic.borrow_mut() = topic; *self.topic.borrow_mut() = topic;
} }
#[instrument(name = "Space", skip_all)]
async fn on_new_name(&self, name: Option<String>) { async fn on_new_name(&self, name: Option<String>) {
error!("Space::on_new_name({:?})", name); trace!("on_new_name");
self.name.borrow_mut().clone_from(&name); self.name.borrow_mut().clone_from(&name);
if let Some(store) = self.store.borrow().as_ref() { if let Some(store) = self.store.borrow().as_ref() {

View File

@@ -1,6 +1,7 @@
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
use matrix_sdk::{ruma::OwnedRoomId, RoomState}; use matrix_sdk::{ruma::OwnedRoomId, RoomState};
use tracing::Span;
use super::room_event::RoomEventsReceiver; use super::room_event::RoomEventsReceiver;
use crate::{domain::model::space::SpaceId, utils::Sender}; use crate::{domain::model::space::SpaceId, utils::Sender};
@@ -16,6 +17,7 @@ pub enum AccountEvent {
RoomState, RoomState,
RoomEventsReceiver, RoomEventsReceiver,
Sender<bool>, Sender<bool>,
Span,
), ),
NewSpace( NewSpace(
@@ -24,23 +26,33 @@ pub enum AccountEvent {
Option<String>, Option<String>,
RoomEventsReceiver, RoomEventsReceiver,
Sender<bool>, Sender<bool>,
Span,
), ),
} }
impl Debug for AccountEvent { impl Debug for AccountEvent {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::NewRoom(id, spaces, name, topic, is_direct, state, _events_receiver, _sender) => { Self::NewRoom(
f.debug_tuple("AccountEvent::NewRoom") id,
spaces,
name,
topic,
is_direct,
state,
_events_receiver,
_sender,
_span,
) => f
.debug_tuple("AccountEvent::NewRoom")
.field(id) .field(id)
.field(spaces) .field(spaces)
.field(name) .field(name)
.field(topic) .field(topic)
.field(is_direct) .field(is_direct)
.field(state) .field(state)
.finish() .finish(),
} Self::NewSpace(id, name, topic, _events_receiver, _sender, _span) => f
Self::NewSpace(id, name, topic, _events_receiver, _sender) => f
.debug_tuple("AccountEvent::NewSpace") .debug_tuple("AccountEvent::NewSpace")
.field(id) .field(id)
.field(name) .field(name)

View File

@@ -28,13 +28,12 @@ use matrix_sdk::{
}, },
Client as MatrixClient, RoomMemberships, RoomState, Client as MatrixClient, RoomMemberships, RoomState,
}; };
use tokio::sync::{ use tokio::sync::{
broadcast, broadcast,
broadcast::{error::SendError, Receiver, Sender}, broadcast::{error::SendError, Receiver, Sender},
mpsc::{unbounded_channel, UnboundedReceiver}, mpsc::{unbounded_channel, UnboundedReceiver},
}; };
use tracing::{debug, error, warn}; use tracing::{debug, debug_span, error, instrument, warn, Instrument, Span};
use super::{ use super::{
account_event::AccountEvent, account_event::AccountEvent,
@@ -75,7 +74,7 @@ impl Senders {
if let Some(room_sender) = room_senders.get(room_id) { if let Some(room_sender) = room_senders.get(room_id) {
if let Err(err) = room_sender.send(event) { if let Err(err) = room_sender.send(event) {
error!("Unable to send event to the {room_id} room: {err}"); warn!("Unable to send event to the {room_id} room: {err}");
return Err(err); return Err(err);
} }
} else { } else {
@@ -117,12 +116,15 @@ impl Client {
} }
} }
#[instrument(skip_all)]
async fn create_space( async fn create_space(
senders: &Ctx<Senders>, senders: &Ctx<Senders>,
room_id: &OwnedRoomId, room_id: &OwnedRoomId,
room: Option<&Room>, room: Option<&Room>,
) -> anyhow::Result<(), SendError<AccountEvent>> { ) -> anyhow::Result<(), SendError<AccountEvent>> {
if let Some(receiver) = senders.add_room(&room_id) { if let Some(receiver) = senders.add_room(room_id) {
let current_span = Span::current();
let mut name = None; let mut name = None;
let mut topic = None; let mut topic = None;
if let Some(room) = room { if let Some(room) = room {
@@ -139,19 +141,21 @@ impl Client {
topic.clone(), topic.clone(),
receiver, receiver,
reply, reply,
current_span.clone(),
); );
if let Err(err) = senders.account_events_sender.send(event) { senders.account_events_sender.send(event)?;
return Err(err);
}
// We're expecting a response indicating that the client is able to compute the next RoomEvent // We're expecting a response indicating that the client is able to compute the next RoomEvent
response.recv().await; response.recv().await;
let events = vec![RoomEvent::NewTopic(topic), RoomEvent::NewName(name)]; let events = vec![
RoomEvent::NewTopic(topic, current_span.clone()),
RoomEvent::NewName(name, current_span),
];
for event in events { for event in events {
if let Err(_err) = senders.send(&room_id, event.clone()) { if let Err(_err) = senders.send(room_id, event.clone()) {
// TODO: Return an error // TODO: Return an error
} }
} }
@@ -160,6 +164,7 @@ impl Client {
Ok(()) Ok(())
} }
#[instrument(skip_all)]
async fn create_room( async fn create_room(
senders: &Ctx<Senders>, senders: &Ctx<Senders>,
room: &Room, room: &Room,
@@ -172,7 +177,7 @@ impl Client {
let is_direct = match room.is_direct().await { let is_direct = match room.is_direct().await {
Ok(is_direct) => Some(is_direct), Ok(is_direct) => Some(is_direct),
Err(err) => { Err(err) => {
error!("Unable to know if the {room_id} room is direct: {err}"); warn!("Unable to know if the {room_id} room is direct: {err}");
None None
} }
}; };
@@ -205,11 +210,10 @@ impl Client {
room.state(), room.state(),
receiver, receiver,
reply, reply,
Span::current(),
); );
if let Err(err) = senders.account_events_sender.send(event) { senders.account_events_sender.send(event)?;
return Err(err);
}
// We're expecting a response indicating that the client is able to compute the next RoomEvent // We're expecting a response indicating that the client is able to compute the next RoomEvent
response.recv().await; response.recv().await;
@@ -217,6 +221,7 @@ impl Client {
Ok(()) Ok(())
} }
#[instrument(skip_all)]
async fn add_room( async fn add_room(
senders: &Ctx<Senders>, senders: &Ctx<Senders>,
room: &Room, room: &Room,
@@ -255,7 +260,7 @@ impl Client {
let _ = Self::create_space(senders, &parent, None).await; let _ = Self::create_space(senders, &parent, None).await;
} }
let event = RoomEvent::NewChild(room_id.clone()); let event = RoomEvent::NewChild(room_id.clone(), Span::current());
if let Err(_err) = senders.send(&parent, event) { if let Err(_err) = senders.send(&parent, event) {
// TODO: Return an error // TODO: Return an error
} }
@@ -270,7 +275,9 @@ impl Client {
room: Room, room: Room,
senders: Ctx<Senders>, senders: Ctx<Senders>,
) { ) {
let _ = Self::add_room(&senders, &room).await; let span = debug_span!("Matrix::NewRoom", r = ?room.room_id());
let _ = Self::add_room(&senders, &room).instrument(span).await;
} }
// SyncStateEvent: A possibly-redacted state event without a room_id. // SyncStateEvent: A possibly-redacted state event without a room_id.
@@ -279,9 +286,12 @@ impl Client {
room: Room, room: Room,
senders: Ctx<Senders>, senders: Ctx<Senders>,
) { ) {
let _ = Self::add_room(&senders, &room).await; let span = debug_span!("Matrix::NewRoom", r = ?room.room_id());
let _ = Self::add_room(&senders, &room).instrument(span).await;
} }
#[instrument(skip_all)]
fn on_invite_room_member_event( fn on_invite_room_member_event(
user_id: OwnedUserId, user_id: OwnedUserId,
inviter_id: OwnedUserId, inviter_id: OwnedUserId,
@@ -290,15 +300,16 @@ impl Client {
senders: &Ctx<Senders>, senders: &Ctx<Senders>,
) { ) {
if let Some(client_user_id) = matrix_client.user_id() { if let Some(client_user_id) = matrix_client.user_id() {
let is_account_user = user_id == client_user_id;
let room_id = room.room_id(); let room_id = room.room_id();
let is_account_user = user_id == client_user_id;
debug!( debug!(
"{} (account user: {is_account_user}) invited by {} to join the {} room", "{} (account user: {is_account_user}) invited by {} to join the {} room",
&user_id, &inviter_id, &room_id &user_id, &inviter_id, &room_id
); );
let event = RoomEvent::Invitation(user_id, inviter_id, is_account_user); let event =
RoomEvent::Invitation(user_id, inviter_id, is_account_user, Span::current());
if let Err(_err) = senders.send(room_id, event) { if let Err(_err) = senders.send(room_id, event) {
// TODO: Return an error // TODO: Return an error
@@ -306,6 +317,7 @@ impl Client {
} }
} }
#[instrument(skip_all)]
fn on_join_room_member_event( fn on_join_room_member_event(
user_id: OwnedUserId, user_id: OwnedUserId,
displayname: Option<String>, displayname: Option<String>,
@@ -318,9 +330,15 @@ impl Client {
let is_account_user = user_id == client_user_id; let is_account_user = user_id == client_user_id;
let room_id = room.room_id(); let room_id = room.room_id();
error!("{} has joined the {} room", &user_id, &room_id); debug!("{} has joined the {} room", &user_id, &room_id);
let event = RoomEvent::Join(user_id, displayname, avatar_url, is_account_user); let event = RoomEvent::Join(
user_id,
displayname,
avatar_url,
is_account_user,
Span::current(),
);
if let Err(_err) = senders.send(room_id, event) { if let Err(_err) = senders.send(room_id, event) {
// TODO: Return an error // TODO: Return an error
@@ -340,21 +358,35 @@ impl Client {
let user_id = &ev.state_key; let user_id = &ev.state_key;
match ev.content.membership { match ev.content.membership {
MembershipState::Invite => Self::on_invite_room_member_event( MembershipState::Invite => {
let span = debug_span!("Matrix::RoomInvitation", r = ?room.room_id());
span.in_scope(|| {
Self::on_invite_room_member_event(
user_id.clone(), user_id.clone(),
ev.sender, ev.sender,
&room, &room,
&matrix_client, &matrix_client,
&senders, &senders,
), )
MembershipState::Join => Self::on_join_room_member_event( });
}
MembershipState::Join => {
let span =
debug_span!("Matrix::RoomJoin", r = ?room.room_id(), u = ?user_id)
.entered();
span.in_scope(|| {
Self::on_join_room_member_event(
ev.sender, ev.sender,
ev.content.displayname, ev.content.displayname,
ev.content.avatar_url, ev.content.avatar_url,
&room, &room,
&matrix_client, &matrix_client,
&senders, &senders,
), )
});
}
_ => { _ => {
error!("TODO: {:?}", ev); error!("TODO: {:?}", ev);
} }
@@ -377,6 +409,9 @@ impl Client {
if let SyncStateEvent::Original(ev) = ev { if let SyncStateEvent::Original(ev) = ev {
match ev.content.membership { match ev.content.membership {
MembershipState::Invite => { MembershipState::Invite => {
let span = debug_span!("Matrix::RoomInvitation", r = ?room.room_id());
span.in_scope(|| {
let invitee_id = ev.state_key; let invitee_id = ev.state_key;
Self::on_invite_room_member_event( Self::on_invite_room_member_event(
@@ -386,24 +421,30 @@ impl Client {
&matrix_client, &matrix_client,
&senders, &senders,
) )
// .await });
} }
MembershipState::Join => { MembershipState::Join => {
let user_id = ev.sender;
let span = debug_span!("Matrix::RoomJoin", r = ?room.room_id(), u = ?user_id)
.entered();
span.in_scope(|| {
Self::on_join_room_member_event( Self::on_join_room_member_event(
ev.sender, user_id,
ev.content.displayname, ev.content.displayname,
ev.content.avatar_url, ev.content.avatar_url,
&room, &room,
&matrix_client, &matrix_client,
&senders, &senders,
) )
// .await });
} }
_ => error!("TODO"), _ => error!("TODO"),
} }
} }
} }
#[instrument(skip_all)]
async fn on_room_avatar_event(room: &Room, senders: &Ctx<Senders>) { async fn on_room_avatar_event(room: &Room, senders: &Ctx<Senders>) {
let room_id = room.room_id(); let room_id = room.room_id();
let avatar = match room let avatar = match room
@@ -416,12 +457,12 @@ impl Client {
{ {
Ok(avatar) => avatar, Ok(avatar) => avatar,
Err(err) => { Err(err) => {
error!("Unable to fetch avatar for {}: {err}", &room_id); warn!("Unable to fetch avatar for {}: {err}", &room_id);
None None
} }
}; };
let event = RoomEvent::NewAvatar(avatar); let event = RoomEvent::NewAvatar(avatar, Span::current());
if let Err(_err) = senders.send(room_id, event) { if let Err(_err) = senders.send(room_id, event) {
// TODO: Return an error // TODO: Return an error
@@ -433,7 +474,11 @@ impl Client {
room: Room, room: Room,
senders: Ctx<Senders>, senders: Ctx<Senders>,
) { ) {
Self::on_room_avatar_event(&room, &senders).await; let span = debug_span!("Matrix::RoomAvatar", r = ?room.room_id());
Self::on_room_avatar_event(&room, &senders)
.instrument(span)
.await;
} }
async fn on_sync_room_avatar_event( async fn on_sync_room_avatar_event(
@@ -443,13 +488,18 @@ impl Client {
) { ) {
if let SyncStateEvent::Original(_ev) = ev { if let SyncStateEvent::Original(_ev) = ev {
dioxus::prelude::spawn(async move { dioxus::prelude::spawn(async move {
Self::on_room_avatar_event(&room, &senders).await; let span = debug_span!("Matrix::RoomAvatar", r = ?room.room_id());
Self::on_room_avatar_event(&room, &senders)
.instrument(span)
.await;
}); });
} }
} }
#[instrument(skip_all)]
fn on_room_name_event(name: Option<String>, room: &Room, senders: &Ctx<Senders>) { fn on_room_name_event(name: Option<String>, room: &Room, senders: &Ctx<Senders>) {
let event = RoomEvent::NewName(name); let event = RoomEvent::NewName(name, Span::current());
if let Err(_err) = senders.send(room.room_id(), event) { if let Err(_err) = senders.send(room.room_id(), event) {
// TODO: Return an error // TODO: Return an error
@@ -461,7 +511,11 @@ impl Client {
room: Room, room: Room,
senders: Ctx<Senders>, senders: Ctx<Senders>,
) { ) {
let span = debug_span!("Matrix::RoomName", r = ?room.room_id());
span.in_scope(|| {
Self::on_room_name_event(ev.content.name, &room, &senders); Self::on_room_name_event(ev.content.name, &room, &senders);
});
} }
async fn on_sync_room_name_event( async fn on_sync_room_name_event(
@@ -470,12 +524,17 @@ impl Client {
senders: Ctx<Senders>, senders: Ctx<Senders>,
) { ) {
if let SyncStateEvent::Original(ev) = ev { if let SyncStateEvent::Original(ev) = ev {
let span = debug_span!("Matrix::RoomName", r = ?room.room_id());
span.in_scope(|| {
Self::on_room_name_event(Some(ev.content.name), &room, &senders); Self::on_room_name_event(Some(ev.content.name), &room, &senders);
});
} }
} }
#[instrument(skip_all)]
fn on_room_topic_event(topic: Option<String>, room: &Room, senders: &Ctx<Senders>) { fn on_room_topic_event(topic: Option<String>, room: &Room, senders: &Ctx<Senders>) {
let event = RoomEvent::NewTopic(topic); let event = RoomEvent::NewTopic(topic, Span::current());
if let Err(_err) = senders.send(room.room_id(), event) { if let Err(_err) = senders.send(room.room_id(), event) {
// TODO: Return an error // TODO: Return an error
@@ -487,7 +546,11 @@ impl Client {
room: Room, room: Room,
senders: Ctx<Senders>, senders: Ctx<Senders>,
) { ) {
let span = debug_span!("Matrix::RoomTopic", r = ?room.room_id());
span.in_scope(|| {
Self::on_room_topic_event(ev.content.topic, &room, &senders); Self::on_room_topic_event(ev.content.topic, &room, &senders);
});
} }
async fn on_sync_room_topic_event( async fn on_sync_room_topic_event(
@@ -496,7 +559,11 @@ impl Client {
senders: Ctx<Senders>, senders: Ctx<Senders>,
) { ) {
if let SyncStateEvent::Original(ev) = ev { if let SyncStateEvent::Original(ev) = ev {
let span = debug_span!("Matrix::RoomTopic", r = ?room.room_id());
span.in_scope(|| {
Self::on_room_topic_event(Some(ev.content.topic), &room, &senders); Self::on_room_topic_event(Some(ev.content.topic), &room, &senders);
});
} }
} }
@@ -629,7 +696,7 @@ impl Client {
Err(err) => Err(err.into()), Err(err) => Err(err.into()),
} }
} else { } else {
error!("No room found with the \"{}\" id", room_id.as_str()); warn!("No room found with the \"{}\" id", room_id.as_str());
// TODO: Return an error if the room has not been found // TODO: Return an error if the room has not been found
Ok(None) Ok(None)
} }
@@ -644,7 +711,7 @@ impl Client {
Err(err) => Err(err.into()), Err(err) => Err(err.into()),
} }
} else { } else {
error!("No room found with the \"{}\" id", room_id.as_str()); warn!("No room found with the \"{}\" id", room_id.as_str());
// TODO: Return an error if the room has not been found // TODO: Return an error if the room has not been found
Ok(vec![]) Ok(vec![])
} }
@@ -681,8 +748,8 @@ impl Client {
// TODO: Check if we can get member before fetching the data and received an error... // TODO: Check if we can get member before fetching the data and received an error...
match room.get_member(user_id).await { match room.get_member(user_id).await {
Ok(room_member) => match room_member { Ok(room_member) => {
Some(room_member) => { if let Some(room_member) = room_member {
let res = match room_member let res = match room_member
.avatar(MediaFormat::Thumbnail(MediaThumbnailSize { .avatar(MediaFormat::Thumbnail(MediaThumbnailSize {
method: Method::Scale, method: Method::Scale,
@@ -696,16 +763,14 @@ impl Client {
}; };
return res; return res;
} }
// TODO: Error msg }
None => (),
},
Err(err) => { Err(err) => {
error!("Unable to get room member {user_id}: {err}"); warn!("Unable to get room member {user_id}: {err}");
if let Some(avatar_url) = avatar_url { if let Some(avatar_url) = avatar_url {
let thumbnail = self.get_thumbnail(avatar_url.clone()).await; let thumbnail = self.get_thumbnail(avatar_url.clone()).await;
return Ok(Some(thumbnail?)); return Ok(Some(thumbnail?));
} else { } else {
error!("No avatar url set for the {room_id} room"); debug!("No avatar url set for the {room_id} room");
} }
} }
} }

View File

@@ -1,12 +1,13 @@
use std::{collections::HashMap, rc::Rc}; use std::{collections::HashMap, rc::Rc};
use async_trait::async_trait; use async_trait::async_trait;
use matrix_sdk::ruma::{OwnedMxcUri, OwnedRoomId, OwnedUserId};
use tokio::{ use tokio::{
select, select,
sync::{broadcast::Receiver, mpsc::UnboundedSender}, sync::{broadcast::Receiver, mpsc::UnboundedSender},
}; };
use tokio_stream::{wrappers::BroadcastStream, StreamExt, StreamMap}; use tokio_stream::{wrappers::BroadcastStream, StreamExt, StreamMap};
use tracing::error; use tracing::{error, instrument, Instrument};
use super::{ use super::{
account_event::AccountEvent, account_event::AccountEvent,
@@ -96,6 +97,96 @@ impl Requester {
pub async fn login(&self, style: LoginStyle) -> anyhow::Result<()> { pub async fn login(&self, style: LoginStyle) -> anyhow::Result<()> {
request_to_worker!(self, WorkerTask::Login, style) request_to_worker!(self, WorkerTask::Login, style)
} }
#[instrument(skip_all)]
async fn on_room_invitation(
consumer: &Rc<dyn RoomMessagingConsumerInterface>,
user_id: OwnedUserId,
sender_id: OwnedUserId,
is_account_user: bool,
) {
let invitation = Invitation::new(user_id, sender_id, is_account_user);
consumer.on_invitation(invitation).await;
}
#[instrument(skip_all)]
async fn on_room_join(
consumer: &Rc<dyn RoomMessagingConsumerInterface>,
room_id: OwnedRoomId,
user_id: OwnedUserId,
user_name: Option<String>,
avatar_url: Option<OwnedMxcUri>,
is_account_user: bool,
messaging_provider: Rc<dyn MemberMessagingProviderInterface>,
) {
let member = RoomMember::new(
UserId::from(user_id),
user_name,
avatar_url,
room_id,
is_account_user,
messaging_provider,
);
consumer.on_membership(member).await;
}
#[instrument(skip_all)]
async fn on_room_new_topic(
consumer: &Rc<dyn RoomMessagingConsumerInterface>,
topic: Option<String>,
) {
consumer.on_new_topic(topic).await;
}
#[instrument(skip_all)]
async fn on_room_new_name(
consumer: &Rc<dyn RoomMessagingConsumerInterface>,
name: Option<String>,
) {
consumer.on_new_name(name).await;
}
#[instrument(skip_all)]
async fn on_room_new_avatar(
consumer: &Rc<dyn RoomMessagingConsumerInterface>,
avatar: Option<Avatar>,
) {
consumer.on_new_avatar(avatar).await;
}
#[instrument(skip_all)]
async fn on_space_new_child(
consumer: &Rc<dyn SpaceMessagingConsumerInterface>,
child_id: RoomId,
) {
// TODO: Make name consistent
consumer.on_child(child_id).await;
}
#[instrument(skip_all)]
async fn on_space_new_topic(
consumer: &Rc<dyn SpaceMessagingConsumerInterface>,
topic: Option<String>,
) {
consumer.on_new_topic(topic).await;
}
#[instrument(skip_all)]
async fn on_space_new_name(
consumer: &Rc<dyn SpaceMessagingConsumerInterface>,
name: Option<String>,
) {
consumer.on_new_name(name).await;
}
// #[instrument(name="SpaceAvatar", skip_all, fields(s = %space_id, a = avatar.is_some()))]
// async fn on_space_new_avatar(
// consumer: &Rc<dyn SpaceMessagingConsumerInterface>,
// space_id: OwnedRoomId,
// avatar: Option<Avatar>,
// ) {
// consumer.on_new_avatar(avatar).await;
// }
} }
#[async_trait(?Send)] #[async_trait(?Send)]
@@ -140,7 +231,17 @@ impl AccountMessagingProviderInterface for Requester {
res = account_events_receiver.recv() => { res = account_events_receiver.recv() => {
if let Ok(account_event) = res { if let Ok(account_event) = res {
match account_event { match account_event {
AccountEvent::NewRoom(id, spaces, name, topic, is_direct, state, receiver, new_room_tx) => { AccountEvent::NewRoom(
id,
spaces,
name,
topic,
is_direct,
state,
receiver,
new_room_tx,
span
) => {
let mut room = Room::new(id, spaces, name, topic, is_direct, Some(state)); let mut room = Room::new(id, spaces, name, topic, is_direct, Some(state));
let room_id = room.id().clone(); let room_id = room.id().clone();
@@ -151,13 +252,15 @@ impl AccountMessagingProviderInterface for Requester {
let stream = BroadcastStream::new(receiver.into()); let stream = BroadcastStream::new(receiver.into());
rooms_events_streams.insert(room_id.clone(), stream); rooms_events_streams.insert(room_id.clone(), stream);
let room_events_consumer = account_events_consumer.on_new_room(room).await; let room_events_consumer = account_events_consumer.on_new_room(room)
.instrument(span)
.await;
room_events_consumers.insert(room_id, room_events_consumer); room_events_consumers.insert(room_id, room_events_consumer);
// We're now ready to recv and compute RoomEvent. // We're now ready to recv and compute RoomEvent.
new_room_tx.send(true).await; new_room_tx.send(true).await;
}, },
AccountEvent::NewSpace(id, name, topic, receiver, new_space_tx) => { AccountEvent::NewSpace(id, name, topic, receiver, new_space_tx, span) => {
let mut space = Space::new(id, name, topic); let mut space = Space::new(id, name, topic);
let space_id = space.id().clone(); let space_id = space.id().clone();
@@ -168,12 +271,14 @@ impl AccountMessagingProviderInterface for Requester {
let stream = BroadcastStream::new(receiver.into()); let stream = BroadcastStream::new(receiver.into());
spaces_events_streams.insert(space_id.clone(), stream); spaces_events_streams.insert(space_id.clone(), stream);
let space_events_consumer = account_events_consumer.on_new_space(space).await; let space_events_consumer = account_events_consumer.on_new_space(space)
.instrument(span)
.await;
space_events_consumers.insert(space_id, space_events_consumer); space_events_consumers.insert(space_id, space_events_consumer);
// We're now ready to recv and compute SpaceEvent. // We're now ready to recv and compute SpaceEvent.
new_space_tx.send(true).await; new_space_tx.send(true).await;
} },
}; };
} }
}, },
@@ -181,33 +286,43 @@ impl AccountMessagingProviderInterface for Requester {
if let Ok(room_event) = room_event { if let Ok(room_event) = room_event {
if let Some(consumer) = room_events_consumers.get(&room_id) { if let Some(consumer) = room_events_consumers.get(&room_id) {
match room_event { match room_event {
RoomEvent::Invitation(user_id, sender_id, is_account_user) => { RoomEvent::Invitation(user_id, sender_id, is_account_user, span) => {
let invitation = Invitation::new(user_id, sender_id, is_account_user); Self::on_room_invitation(consumer, user_id, sender_id, is_account_user)
consumer.on_invitation(invitation).await; .instrument(span)
.await;
}, },
RoomEvent::Join(user_id, user_name, avatar_url, is_account_user) => { RoomEvent::Join(user_id, user_name, avatar_url, is_account_user, span) => {
let member = RoomMember::new( Self::on_room_join(
UserId::from(user_id), consumer,
room_id,
user_id,
user_name, user_name,
avatar_url, avatar_url,
room_id,
is_account_user, is_account_user,
client.clone()); client.clone())
consumer.on_membership(member).await; .instrument(span)
.await;
}, },
RoomEvent::NewTopic(topic) => { RoomEvent::NewTopic(topic, span) => {
consumer.on_new_topic(topic).await; Self::on_room_new_topic(consumer, topic)
.instrument(span)
.await;
}, },
RoomEvent::NewName(name) => { RoomEvent::NewName(name, span) => {
consumer.on_new_name(name).await; Self::on_room_new_name(consumer, name)
.instrument(span)
.await;
}, },
RoomEvent::NewAvatar(avatar) => { RoomEvent::NewAvatar(avatar, span) => {
consumer.on_new_avatar(avatar).await; Self::on_room_new_avatar(consumer, avatar)
.instrument(span)
.await;
} }
_ => {} // RoomEvent::NewAvatar(avatar) => Self::on_room_new_avatar(consumer, avatar).await,
_ => error!("TODO: {:?}", &room_event),
} }
} else { } else {
error!("No consumer found for \"{}\" room", room_id); error!("No consumer found for {} room", &room_id);
} }
} }
}, },
@@ -215,19 +330,25 @@ impl AccountMessagingProviderInterface for Requester {
if let Ok(room_event) = room_event { if let Ok(room_event) = room_event {
if let Some(consumer) = space_events_consumers.get(&space_id) { if let Some(consumer) = space_events_consumers.get(&space_id) {
match room_event { match room_event {
RoomEvent::NewTopic(topic) => { RoomEvent::NewTopic(topic, span) => {
consumer.on_new_topic(topic).await; Self::on_space_new_topic(consumer, topic)
.instrument(span)
.await;
}, },
RoomEvent::NewName(name) => { RoomEvent::NewName(name, span) => {
consumer.on_new_name(name).await; Self::on_space_new_name(consumer, name)
.instrument(span)
.await;
}, },
RoomEvent::NewChild(child_id) => { RoomEvent::NewChild(child_id, span) => {
consumer.on_child(child_id).await; Self::on_space_new_child(consumer, child_id)
.instrument(span)
.await;
}, },
_ => {} _ => error!("TODO: {:?}", &room_event),
} }
} else { } else {
error!("No consumer found for \"{}\" space", space_id); error!("No consumer found for {} space", &space_id);
} }
} }
} }

View File

@@ -2,43 +2,47 @@ use std::fmt::{Debug, Formatter};
use matrix_sdk::ruma::{OwnedMxcUri, OwnedRoomId, OwnedUserId}; use matrix_sdk::ruma::{OwnedMxcUri, OwnedRoomId, OwnedUserId};
use tokio::sync::broadcast::Receiver; use tokio::sync::broadcast::Receiver;
use tracing::Span;
use crate::domain::model::common::Avatar; use crate::domain::model::common::Avatar;
#[derive(Clone)] #[derive(Clone)]
pub enum RoomEvent { pub enum RoomEvent {
Invitation(OwnedUserId, OwnedUserId, bool), Invitation(OwnedUserId, OwnedUserId, bool, Span),
Join(OwnedUserId, Option<String>, Option<OwnedMxcUri>, bool), Join(OwnedUserId, Option<String>, Option<OwnedMxcUri>, bool, Span),
NewTopic(Option<String>), NewTopic(Option<String>, Span),
NewName(Option<String>), NewName(Option<String>, Span),
NewAvatar(Option<Avatar>), NewAvatar(Option<Avatar>, Span),
NewChild(OwnedRoomId), NewChild(OwnedRoomId, Span),
} }
impl Debug for RoomEvent { impl Debug for RoomEvent {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
match self { match self {
Self::Invitation(invitee_id, sender_id, is_account_user) => f Self::Invitation(invitee_id, sender_id, is_account_user, _span) => f
.debug_tuple("RoomEvent::Invitation") .debug_tuple("RoomEvent::Invitation")
.field(invitee_id) .field(invitee_id)
.field(sender_id) .field(sender_id)
.field(is_account_user) .field(is_account_user)
.finish(), .finish(),
Self::Join(user_id, user_name, avatar_url, is_account_user) => f Self::Join(user_id, user_name, avatar_url, is_account_user, _span) => f
.debug_tuple("RoomEvent::Join") .debug_tuple("RoomEvent::Join")
.field(user_id) .field(user_id)
.field(user_name) .field(user_name)
.field(avatar_url) .field(avatar_url)
.field(is_account_user) .field(is_account_user)
.finish(), .finish(),
Self::NewTopic(topic) => f.debug_tuple("RoomEvent::NewTopic").field(topic).finish(), Self::NewTopic(topic, _span) => {
Self::NewName(name) => f.debug_tuple("RoomEvent::NewName").field(name).finish(), f.debug_tuple("RoomEvent::NewTopic").field(topic).finish()
Self::NewAvatar(avatar) => f }
Self::NewName(name, _span) => f.debug_tuple("RoomEvent::NewName").field(name).finish(),
Self::NewAvatar(avatar, _span) => f
// Self::NewAvatar(avatar) => f
.debug_tuple("RoomEvent::NewAvatar") .debug_tuple("RoomEvent::NewAvatar")
.field(&format!("is_some: {}", &avatar.is_some())) .field(&format!("is_some: {}", &avatar.is_some()))
.finish(), .finish(),
Self::NewChild(room_id) => f Self::NewChild(room_id, _span) => f
.debug_tuple("SpaceEvent::NewChild") .debug_tuple("SpaceEvent::NewChild")
.field(room_id) .field(room_id)
.finish(), .finish(),

View File

@@ -10,7 +10,10 @@ mod utils;
use dioxus::prelude::*; use dioxus::prelude::*;
use tracing::{debug, error}; use tracing::{debug, error};
use tracing_forest::ForestLayer;
use tracing_subscriber::prelude::*; use tracing_subscriber::prelude::*;
use tracing_subscriber::EnvFilter;
cfg_if! { cfg_if! {
if #[cfg(feature = "desktop")] { if #[cfg(feature = "desktop")] {
@@ -111,36 +114,34 @@ fn main() {
let mut layers = Vec::new(); let mut layers = Vec::new();
cfg_if! { cfg_if! {
if #[cfg(feature = "desktop")] { if #[cfg(target_family = "wasm")] {
let config = Config::new().with_menu(None);;
builder = builder.with_cfg(config);
let log_file = File::create("/tmp/bg92.log").unwrap();
let file_layer = tracing_subscriber::fmt::layer()
.with_writer(log_file)
.with_timer(UtcTime::new(Iso8601::DATE_TIME))
.with_ansi(false)
.with_filter(tracing::level_filters::LevelFilter::WARN)
.boxed();
layers.push(file_layer);
let console_layer = tracing_subscriber::fmt::layer()
// .with_filter(tracing::level_filters::LevelFilter::DEBUG);
.with_filter(tracing::level_filters::LevelFilter::WARN)
.boxed();
layers.push(console_layer);
} else if #[cfg(feature = "web")] {
let console_layer = tracing_subscriber::fmt::layer() let console_layer = tracing_subscriber::fmt::layer()
.with_ansi(false) // Only partially supported across browsers .with_ansi(false) // Only partially supported across browsers
.without_time() // std::time is not available in browsers, see note below .without_time() // std::time is not available in browsers, see note below
.with_writer(MakeWebConsoleWriter::new()) // write events to the console .with_writer(MakeWebConsoleWriter::new()) // write events to the console
.with_filter(tracing::level_filters::LevelFilter::INFO); .boxed();
layers.push(console_layer);
} else {
let config = Config::new().with_menu(None);
builder = builder.with_cfg(config);
let log_file = File::create("/tmp/bg92.log").unwrap();
let file_layer = tracing_subscriber::fmt::layer()
.with_ansi(false)
.with_writer(log_file)
.with_timer(UtcTime::new(Iso8601::DATE_TIME))
.boxed();
layers.push(file_layer);
let console_layer = ForestLayer::default().boxed();
layers.push(console_layer); layers.push(console_layer);
} }
} }
tracing_subscriber::registry().with(layers).init(); tracing_subscriber::registry()
.with(layers)
.with(EnvFilter::from_default_env())
.init();
builder.launch(app); builder.launch(app);
} }

View File

@@ -35,7 +35,7 @@ pub struct Room {
impl Room { impl Room {
pub fn signal(&self) -> Store { pub fn signal(&self) -> Store {
self.store.borrow().clone() *self.store.borrow()
} }
pub fn from_domain(room: Rc<dyn RoomStoreConsumerInterface>) -> Self { pub fn from_domain(room: Rc<dyn RoomStoreConsumerInterface>) -> Self {

View File

@@ -25,7 +25,7 @@ pub struct Space {
impl Space { impl Space {
pub fn signal(&self) -> Store { pub fn signal(&self) -> Store {
self.store.borrow().clone() *self.store.borrow()
} }
pub fn from_domain(space: Rc<dyn SpaceStoreConsumerInterface>) -> Self { pub fn from_domain(space: Rc<dyn SpaceStoreConsumerInterface>) -> Self {