mirror of https://github.com/buster-so/buster.git
161 lines
5.0 KiB
Rust
161 lines
5.0 KiB
Rust
use anyhow::{anyhow, Result};
|
|
use diesel::{update, ExpressionMethods};
|
|
use diesel_async::RunQueryDsl;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::sync::Arc;
|
|
|
|
use uuid::Uuid;
|
|
use middleware::AuthenticatedUser;
|
|
|
|
use database::{pool::get_pg_pool,
|
|
schema::threads_deprecated,};
|
|
use crate::{
|
|
routes::ws::{
|
|
ws::{SubscriptionRwLock, WsErrorCode, WsEvent, WsResponseMessage, WsSendMethod},
|
|
ws_router::WsRoutes,
|
|
ws_utils::{send_error_message, send_ws_message},
|
|
},
|
|
utils::clients::sentry_utils::send_sentry_error,
|
|
};
|
|
|
|
use super::threads_router::{ThreadEvent, ThreadRoute};
|
|
|
|
#[derive(Deserialize, Debug, Clone)]
|
|
pub struct DeleteThreadRequest {
|
|
pub ids: Vec<Uuid>,
|
|
}
|
|
|
|
#[derive(Serialize, Debug, Clone)]
|
|
pub struct DeleteThreadRes {
|
|
pub id: Uuid,
|
|
}
|
|
|
|
pub async fn delete_thread(
|
|
subscriptions: &Arc<SubscriptionRwLock>,
|
|
user: &AuthenticatedUser,
|
|
req: DeleteThreadRequest,
|
|
) -> Result<()> {
|
|
let mut delete_tasks = Vec::new();
|
|
|
|
for id in req.ids {
|
|
let subscription = format!("thread:{}", id);
|
|
|
|
let delete_thread_res = match delete_thread_handler(user, &id).await {
|
|
Ok(res) => res,
|
|
Err(e) => {
|
|
tracing::error!("Error getting thread: {}", e);
|
|
send_sentry_error(&e.to_string(), None);
|
|
send_error_message(
|
|
&user.id.to_string(),
|
|
WsRoutes::Threads(ThreadRoute::Delete),
|
|
WsEvent::Threads(ThreadEvent::DeleteThreadState),
|
|
WsErrorCode::InternalServerError,
|
|
"Failed to delete thread.".to_string(),
|
|
user,
|
|
)
|
|
.await?;
|
|
return Err(anyhow!("Error getting thread: {}", e));
|
|
}
|
|
};
|
|
|
|
delete_tasks.push(delete_thread_res);
|
|
|
|
let delete_thread_res_message = WsResponseMessage::new(
|
|
WsRoutes::Threads(ThreadRoute::Delete),
|
|
WsEvent::Threads(ThreadEvent::DeleteThreadState),
|
|
vec![id],
|
|
None,
|
|
user,
|
|
WsSendMethod::All,
|
|
);
|
|
|
|
match send_ws_message(&subscription, &delete_thread_res_message).await {
|
|
Ok(_) => {}
|
|
Err(e) => {
|
|
tracing::error!("Error sending message to pubsub: {}", e);
|
|
let err = anyhow!("Error sending message to pubsub: {}", e);
|
|
send_sentry_error(&err.to_string(), Some(&user.id));
|
|
return Err(err);
|
|
}
|
|
}
|
|
|
|
subscriptions.remove(subscription.clone()).await;
|
|
}
|
|
|
|
let mut delete_responses = Vec::new();
|
|
|
|
for task in delete_tasks {
|
|
match task.await {
|
|
Ok(Ok(res)) => delete_responses.push(res.id),
|
|
Ok(Err(e)) => {
|
|
tracing::error!("Unable to insert thread into database: {:?}", e);
|
|
let err = anyhow!("Unable to insert thread into database: {}", e);
|
|
send_sentry_error(&err.to_string(), Some(&user.id));
|
|
return Err(err);
|
|
}
|
|
Err(e) => {
|
|
tracing::error!("Unable to insert thread into database: {:?}", e);
|
|
let err = anyhow!("Unable to insert thread into database: {}", e);
|
|
send_sentry_error(&err.to_string(), Some(&user.id));
|
|
return Err(err);
|
|
}
|
|
}
|
|
}
|
|
|
|
let delete_thread_res_message = WsResponseMessage::new(
|
|
WsRoutes::Threads(ThreadRoute::Delete),
|
|
WsEvent::Threads(ThreadEvent::DeleteThreadState),
|
|
delete_responses,
|
|
None,
|
|
user,
|
|
WsSendMethod::All,
|
|
);
|
|
|
|
match send_ws_message(&user.id.to_string(), &delete_thread_res_message).await {
|
|
Ok(_) => {}
|
|
Err(e) => {
|
|
tracing::error!("Error sending message to pubsub: {}", e);
|
|
let err = anyhow!("Error sending message to pubsub: {}", e);
|
|
send_sentry_error(&err.to_string(), Some(&user.id));
|
|
return Err(err);
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
async fn delete_thread_handler(
|
|
user: &AuthenticatedUser,
|
|
id: &Uuid,
|
|
) -> Result<tokio::task::JoinHandle<Result<DeleteThreadRes>>> {
|
|
let mut conn = get_pg_pool().get().await.map_err(|e| {
|
|
tracing::error!("Error getting connection from pool: {}", e);
|
|
let err = anyhow!("Error getting connection: {}", e);
|
|
send_sentry_error(&err.to_string(), Some(&user.id));
|
|
err
|
|
})?;
|
|
|
|
let id = id.clone();
|
|
|
|
let delete_thread_task = tokio::task::spawn(async move {
|
|
match update(threads_deprecated::table)
|
|
.filter(threads_deprecated::id.eq(&id))
|
|
.set(threads_deprecated::deleted_at.eq(chrono::Utc::now()))
|
|
.execute(&mut conn)
|
|
.await
|
|
{
|
|
Ok(_) => (),
|
|
Err(e) => {
|
|
tracing::error!("Unable to insert thread: {:?}", e);
|
|
let err = anyhow!("Unable to insert thread: {}", e);
|
|
send_sentry_error(&err.to_string(), None);
|
|
return Err(err);
|
|
}
|
|
}
|
|
|
|
Ok(DeleteThreadRes { id })
|
|
});
|
|
|
|
Ok(delete_thread_task)
|
|
}
|