Remove unsafe block and switch to safe mutex

This commit is contained in:
lidar 2023-08-08 21:43:23 +09:00
parent b109500142
commit fa5ec206e6
3 changed files with 23 additions and 12 deletions

5
Cargo.lock generated
View File

@ -801,9 +801,9 @@ dependencies = [
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.17.1" version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]] [[package]]
name = "overload" name = "overload"
@ -1396,6 +1396,7 @@ dependencies = [
"diesel_migrations", "diesel_migrations",
"lazy_static", "lazy_static",
"num_cpus", "num_cpus",
"once_cell",
"regex", "regex",
"reqwest", "reqwest",
"rocket", "rocket",

View File

@ -11,6 +11,7 @@ diesel_logger = "0.3.0"
diesel_migrations = "2.1.0" diesel_migrations = "2.1.0"
lazy_static = "1.4.0" lazy_static = "1.4.0"
num_cpus = "1.16.0" num_cpus = "1.16.0"
once_cell = "1.18.0"
regex = "1.9.3" regex = "1.9.3"
reqwest = {version = "0.11.18", features = ["json", "rustls-tls", "gzip", "brotli"], default-features = false} reqwest = {version = "0.11.18", features = ["json", "rustls-tls", "gzip", "brotli"], default-features = false}
rocket = {git = "https://github.com/SergioBenitez/Rocket"} rocket = {git = "https://github.com/SergioBenitez/Rocket"}

View File

@ -2,19 +2,22 @@
extern crate rocket; extern crate rocket;
use std::path::Path; use std::path::Path;
use std::sync::Arc;
use std::thread::sleep; use std::thread::sleep;
use std::time::{Duration, Instant, SystemTime}; use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
use diesel::connection::SimpleConnection; use diesel::connection::SimpleConnection;
use rocket::{Build, Request, Response, Rocket}; use once_cell::sync::Lazy;
use rocket::fairing::{AdHoc, Fairing, Info, Kind}; use rocket::fairing::{AdHoc, Fairing, Info, Kind};
use rocket::http::Header; use rocket::http::Header;
use rocket::{Build, Request, Response, Rocket};
use rocket_sync_db_pools::database; use rocket_sync_db_pools::database;
use tokio::sync::Mutex;
use tokio::time::interval; use tokio::time::interval;
use structs::{Segment, Sponsor}; use structs::{Segment, Sponsor};
use crate::routes::{skip_segments, skip_segments_by_id, fake_is_user_vip, fake_user_info}; use crate::routes::{fake_is_user_vip, fake_user_info, skip_segments, skip_segments_by_id};
mod models; mod models;
mod routes; mod routes;
@ -34,7 +37,8 @@ async fn run_migrations(rocket: Rocket<Build>) -> Rocket<Build> {
.run(|c| { .run(|c| {
MigrationHarness::run_pending_migrations(c, MIGRATIONS) MigrationHarness::run_pending_migrations(c, MIGRATIONS)
.expect("Failed to run migrations"); .expect("Failed to run migrations");
}).await; })
.await;
rocket rocket
} }
@ -52,7 +56,10 @@ impl Fairing for CORS {
async fn on_response<'r>(&self, request: &'r Request<'_>, response: &mut Response<'r>) { async fn on_response<'r>(&self, request: &'r Request<'_>, response: &mut Response<'r>) {
response.set_header(Header::new("Access-Control-Allow-Origin", "*")); response.set_header(Header::new("Access-Control-Allow-Origin", "*"));
response.set_header(Header::new("Access-Control-Allow-Methods", "POST, GET, PATCH, OPTIONS")); response.set_header(Header::new(
"Access-Control-Allow-Methods",
"POST, GET, PATCH, OPTIONS",
));
response.set_header(Header::new("Access-Control-Allow-Headers", "*")); response.set_header(Header::new("Access-Control-Allow-Headers", "*"));
response.set_header(Header::new("Access-Control-Allow-Credentials", "true")); response.set_header(Header::new("Access-Control-Allow-Credentials", "true"));
if request.method() == rocket::http::Method::Options { if request.method() == rocket::http::Method::Options {
@ -62,7 +69,8 @@ impl Fairing for CORS {
} }
} }
static mut LAST_UPDATE: Option<SystemTime> = None; static LAST_UPDATE: Lazy<Arc<Mutex<SystemTime>>> =
Lazy::new(|| Arc::new(Mutex::new(SystemTime::UNIX_EPOCH)));
#[launch] #[launch]
fn rocket() -> Rocket<Build> { fn rocket() -> Rocket<Build> {
@ -80,16 +88,17 @@ fn rocket() -> Rocket<Build> {
tokio::spawn(async move { tokio::spawn(async move {
loop { loop {
interval.tick().await; interval.tick().await;
let last_update = unsafe { LAST_UPDATE }; let mut lock_guard = LAST_UPDATE.lock().await;
let locked_last_updated_time = &mut *lock_guard;
// see if file exists // see if file exists
if path.exists() && (last_update.is_none() || last_update.unwrap().elapsed().unwrap_or_default().as_secs() > 60) { if path.exists() && (*locked_last_updated_time == UNIX_EPOCH || locked_last_updated_time.elapsed().unwrap_or_default().as_secs() > 60) {
// Check last modified time // Check last modified time
let last_modified = path.metadata().unwrap().modified().unwrap(); let last_modified = path.metadata().unwrap().modified().unwrap();
// Check if file was modified since last update // Check if file was modified since last update
if last_update.is_none() || last_modified > last_update.unwrap() { if *locked_last_updated_time == UNIX_EPOCH || last_modified > *locked_last_updated_time {
// Use COPY FROM to import the CSV file // Use COPY FROM to import the CSV file
let start = Instant::now(); let start = Instant::now();
@ -114,7 +123,7 @@ fn rocket() -> Rocket<Build> {
}).await; }).await;
if res { if res {
unsafe { LAST_UPDATE = Some(last_modified) }; *LAST_UPDATE.lock().await = last_modified;
} }
} }