Matrix errors, retry

This commit is contained in:
Pascal Engélibert 2022-10-25 18:22:49 +02:00
commit b52dff12fe
Signed by: tuxmain
GPG key ID: 3504BC6D362F7DCA
5 changed files with 182 additions and 137 deletions

View file

@ -1,64 +1,129 @@
use crate::config::Config;
use crossbeam_channel::Receiver;
use log::error;
use matrix_sdk::ruma;
use std::sync::Arc;
use std::{
sync::Arc,
time::{Duration, SystemTime},
};
enum OptionSince<T> {
Some(T),
NoneSince(SystemTime),
}
impl<T> OptionSince<T> {
fn from_result<E, F: FnOnce(E)>(result: Result<T, E>, f: F) -> Self {
match result {
Ok(val) => Self::Some(val),
Err(e) => {
f(e);
Self::NoneSince(SystemTime::now())
}
}
}
}
impl<T> From<Option<T>> for OptionSince<T> {
fn from(opt: Option<T>) -> Self {
match opt {
Some(val) => Self::Some(val),
None => Self::NoneSince(SystemTime::now()),
}
}
}
struct Notifier {
matrix: Option<(matrix_sdk::Client, matrix_sdk::room::Joined)>,
matrix: Option<OptionSince<(matrix_sdk::Client, matrix_sdk::room::Joined)>>,
}
impl Notifier {
async fn new(config: &Config) -> Self {
Self {
matrix: if config.matrix_notify {
let user = ruma::UserId::parse(&config.matrix_user).unwrap();
let client = matrix_sdk::Client::builder()
.homeserver_url(&config.matrix_server)
.user_agent("Webcomment")
.build()
.await
.unwrap();
client
.login_username(&user, &config.matrix_password)
.send()
.await
.unwrap();
client
.sync_once(matrix_sdk::config::SyncSettings::default())
.await
.unwrap();
let room_id = <&ruma::RoomId>::try_from(config.matrix_room.as_str()).unwrap();
let room = client.get_room(room_id).unwrap();
if let matrix_sdk::room::Room::Joined(room) = room {
Some((client, room))
} else {
None
}
Some(OptionSince::from_result(init_matrix(config).await, |e| {
error!("Cannot init Matrix: {:?}", e)
}))
} else {
None
},
}
}
async fn notify(&self) {
if let Some((_client, room)) = &self.matrix {
room.send(
ruma::events::room::message::RoomMessageEventContent::text_plain("New comment."),
None,
)
.await
.unwrap();
async fn notify(&mut self, config: &Config) {
match &self.matrix {
None => {}
Some(OptionSince::Some((_client, room))) => {
room.send(
ruma::events::room::message::RoomMessageEventContent::text_plain(
"New comment.",
),
None,
)
.await
.unwrap();
}
Some(OptionSince::NoneSince(earlier)) => {
if SystemTime::now().duration_since(*earlier).unwrap()
> Duration::from_secs(config.matrix_retry_timeout)
{
self.matrix = Some(OptionSince::from_result(init_matrix(config).await, |e| {
error!("Cannot init Matrix: {:?}", e)
}))
}
}
}
}
}
pub async fn run_notifier(config: Arc<Config>, recv: Receiver<()>) {
let notifier = Notifier::new(&config).await;
let mut notifier = Notifier::new(&config).await;
for () in recv {
notifier.notify().await;
notifier.notify(&config).await;
}
}
#[derive(Debug)]
enum MatrixError {
CannotConnect(matrix_sdk::ClientBuildError),
CannotLogin(matrix_sdk::Error),
CannotSync(matrix_sdk::Error),
RoomNotJoined,
UnknownRoom,
}
async fn init_matrix(
config: &Config,
) -> Result<(matrix_sdk::Client, matrix_sdk::room::Joined), MatrixError> {
let user = ruma::UserId::parse(&config.matrix_user)
.expect("Matrix username should be in format `@user:homeserver`");
let room_id = <&ruma::RoomId>::try_from(config.matrix_room.as_str())
.expect("Matrix room should be in format `#roomname:homeserver` or `!roomid:homeserver`");
let client = matrix_sdk::Client::builder()
.homeserver_url(&config.matrix_server)
.user_agent("Webcomment")
.handle_refresh_tokens()
.build()
.await
.map_err(MatrixError::CannotConnect)?;
client
.login_username(&user, &config.matrix_password)
.send()
.await
.map_err(MatrixError::CannotLogin)?;
client
.sync_once(matrix_sdk::config::SyncSettings::default())
.await
.map_err(MatrixError::CannotSync)?;
let room = client.get_room(room_id).ok_or(MatrixError::UnknownRoom)?;
if let matrix_sdk::room::Room::Joined(room) = room {
Ok((client, room))
} else {
Err(MatrixError::RoomNotJoined)
}
}