Process incoming activities sequentially
This is a quick fix for race conditions occuring during handling of inbox requests.
This commit is contained in:
parent
ae4bfcf614
commit
783c482e9e
2 changed files with 17 additions and 0 deletions
|
@ -1,9 +1,12 @@
|
|||
use std::time::Instant;
|
||||
|
||||
use actix_web::{
|
||||
get, post, web,
|
||||
HttpRequest, HttpResponse, Scope,
|
||||
http::header::HeaderMap,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use tokio::sync::Mutex;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::config::Config;
|
||||
|
@ -100,6 +103,7 @@ async fn actor_view(
|
|||
async fn inbox(
|
||||
config: web::Data<Config>,
|
||||
db_pool: web::Data<Pool>,
|
||||
inbox_mutex: web::Data<Mutex<()>>,
|
||||
request: HttpRequest,
|
||||
activity: web::Json<serde_json::Value>,
|
||||
) -> Result<HttpResponse, HttpError> {
|
||||
|
@ -112,6 +116,14 @@ async fn inbox(
|
|||
} else {
|
||||
log::info!("received in {}: {}", request.uri().path(), activity_type);
|
||||
};
|
||||
let now = Instant::now();
|
||||
// Store mutex guard in a variable to prevent it from being dropped immediately
|
||||
let _guard = inbox_mutex.lock().await;
|
||||
log::info!(
|
||||
"acquired inbox lock after waiting for {:.2?}: {}",
|
||||
now.elapsed(),
|
||||
activity["id"].as_str().unwrap_or_default(),
|
||||
);
|
||||
let db_client = &mut **get_database_client(&db_pool).await?;
|
||||
receive_activity(&config, db_client, &request, &activity).await
|
||||
.map_err(|err| {
|
||||
|
|
|
@ -4,6 +4,7 @@ use actix_web::{
|
|||
App, HttpServer,
|
||||
middleware::Logger as ActixLogger,
|
||||
};
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use mitra::activitypub::views as activitypub;
|
||||
use mitra::atom::views as atom;
|
||||
|
@ -56,6 +57,9 @@ async fn main() -> std::io::Result<()> {
|
|||
config.http_port,
|
||||
);
|
||||
let num_workers = std::cmp::max(num_cpus::get(), 4);
|
||||
// Mutex is used to make server process incoming activities sequentially
|
||||
let inbox_mutex = web::Data::new(Mutex::new(()));
|
||||
|
||||
HttpServer::new(move || {
|
||||
let cors_config = match config.environment {
|
||||
Environment::Development => {
|
||||
|
@ -83,6 +87,7 @@ async fn main() -> std::io::Result<()> {
|
|||
.app_data(web::JsonConfig::default().limit(MAX_UPLOAD_SIZE))
|
||||
.app_data(web::Data::new(config.clone()))
|
||||
.app_data(web::Data::new(db_pool.clone()))
|
||||
.app_data(web::Data::clone(&inbox_mutex))
|
||||
.service(actix_files::Files::new(
|
||||
"/media",
|
||||
config.media_dir(),
|
||||
|
|
Loading…
Reference in a new issue