fix: WAL mode + busy_timeout for SQLite, fix rate limiter TOCTOU race
This commit is contained in:
@@ -48,7 +48,9 @@ async fn wire_dependencies() -> anyhow::Result<AppState> {
|
|||||||
let database_url = std::env::var("DATABASE_URL").context("DATABASE_URL must be set")?;
|
let database_url = std::env::var("DATABASE_URL").context("DATABASE_URL must be set")?;
|
||||||
let opts = SqliteConnectOptions::from_str(&database_url)
|
let opts = SqliteConnectOptions::from_str(&database_url)
|
||||||
.context("Invalid DATABASE_URL")?
|
.context("Invalid DATABASE_URL")?
|
||||||
.create_if_missing(true);
|
.create_if_missing(true)
|
||||||
|
.journal_mode(sqlx::sqlite::SqliteJournalMode::Wal)
|
||||||
|
.busy_timeout(std::time::Duration::from_secs(5));
|
||||||
let pool = SqlitePool::connect_with(opts)
|
let pool = SqlitePool::connect_with(opts)
|
||||||
.await
|
.await
|
||||||
.context("Failed to connect to SQLite database")?;
|
.context("Failed to connect to SQLite database")?;
|
||||||
|
|||||||
@@ -35,15 +35,16 @@ impl RateLimiter {
|
|||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.as_secs()
|
.as_secs()
|
||||||
/ 60;
|
/ 60;
|
||||||
let prev = self.window.load(Ordering::Relaxed);
|
let prev = self.window.load(Ordering::Acquire);
|
||||||
if now != prev {
|
if now != prev {
|
||||||
self.window.store(now, Ordering::Relaxed);
|
// compare_exchange ensures only one thread wins the window reset
|
||||||
self.count.store(1, Ordering::Relaxed);
|
if self.window.compare_exchange(prev, now, Ordering::AcqRel, Ordering::Relaxed).is_ok() {
|
||||||
true
|
self.count.store(1, Ordering::Release);
|
||||||
} else {
|
return true;
|
||||||
self.count.fetch_add(1, Ordering::Relaxed) + 1 <= self.limit
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.count.fetch_add(1, Ordering::Relaxed) + 1 <= self.limit
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_router(state: AppState) -> Router {
|
pub fn build_router(state: AppState) -> Router {
|
||||||
|
|||||||
Reference in New Issue
Block a user