You've already forked AstralRinth
forked from didirus/AstralRinth
Move downloads to queue for better performance (#367)
This commit is contained in:
58
src/queue/download.rs
Normal file
58
src/queue/download.rs
Normal file
@@ -0,0 +1,58 @@
|
||||
use crate::database::models::{DatabaseError, ProjectId, VersionId};
|
||||
use sqlx::PgPool;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
pub struct DownloadQueue {
|
||||
queue: Mutex<Vec<(ProjectId, VersionId)>>,
|
||||
}
|
||||
|
||||
// Batches download transactions every thirty seconds
|
||||
impl DownloadQueue {
|
||||
pub fn new() -> Self {
|
||||
DownloadQueue {
|
||||
queue: Mutex::new(Vec::with_capacity(1000)),
|
||||
}
|
||||
}
|
||||
pub async fn add(&self, project_id: ProjectId, version_id: VersionId) {
|
||||
self.queue.lock().await.push((project_id, version_id));
|
||||
}
|
||||
|
||||
pub async fn take(&self) -> Vec<(ProjectId, VersionId)> {
|
||||
let mut queue = self.queue.lock().await;
|
||||
let len = queue.len();
|
||||
|
||||
std::mem::replace(&mut queue, Vec::with_capacity(len))
|
||||
}
|
||||
|
||||
pub async fn index(&self, pool: &PgPool) -> Result<(), DatabaseError> {
|
||||
let queue = self.take().await;
|
||||
|
||||
if queue.len() > 0 {
|
||||
let mut transaction = pool.begin().await?;
|
||||
|
||||
for (project_id, version_id) in queue {
|
||||
sqlx::query!(
|
||||
"UPDATE versions
|
||||
SET downloads = downloads + 1
|
||||
WHERE (id = $1)",
|
||||
version_id as VersionId
|
||||
)
|
||||
.execute(&mut *transaction)
|
||||
.await?;
|
||||
|
||||
sqlx::query!(
|
||||
"UPDATE mods
|
||||
SET downloads = downloads + 1
|
||||
WHERE (id = $1)",
|
||||
project_id as ProjectId
|
||||
)
|
||||
.execute(&mut *transaction)
|
||||
.await?;
|
||||
}
|
||||
|
||||
transaction.commit().await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
1
src/queue/mod.rs
Normal file
1
src/queue/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod download;
|
||||
Reference in New Issue
Block a user