2023-03-20 21:53:50 +00:00
|
|
|
use std::sync::atomic::{Ordering, AtomicU64, AtomicI64};
|
2022-12-03 02:12:13 +00:00
|
|
|
use std::sync::{RwLock, Arc};
|
|
|
|
|
2023-03-20 21:53:50 +00:00
|
|
|
use serde::Serialize;
|
2022-12-03 02:12:13 +00:00
|
|
|
use warp::Filter;
|
|
|
|
|
|
|
|
use limits_core::json::Base;
|
|
|
|
|
|
|
|
static VISIT_COUNT: AtomicU64 = AtomicU64::new(0);
|
|
|
|
|
2023-03-20 21:53:50 +00:00
|
|
|
static START_TIME: AtomicI64 = AtomicI64::new(0);
|
|
|
|
|
2022-12-03 02:12:13 +00:00
|
|
|
fn get_limits(base: Base) -> impl warp::Reply {
|
|
|
|
VISIT_COUNT.fetch_add(1, Ordering::AcqRel);
|
2023-03-20 21:53:50 +00:00
|
|
|
//println!("Limits got");
|
2022-12-03 02:12:13 +00:00
|
|
|
warp::reply::json(&base)
|
|
|
|
}
|
|
|
|
|
2023-03-20 21:53:50 +00:00
|
|
|
#[derive(Serialize)]
|
|
|
|
struct Visits {
|
|
|
|
visits: u64,
|
|
|
|
since: i64, // Unix time (since epoch)
|
|
|
|
}
|
|
|
|
|
2022-12-03 02:12:13 +00:00
|
|
|
fn get_visits() -> impl warp::Reply {
|
|
|
|
let count = VISIT_COUNT.load(Ordering::Relaxed);
|
2023-03-20 21:53:50 +00:00
|
|
|
let start = START_TIME.load(Ordering::Relaxed);
|
|
|
|
//println!("Count got");
|
|
|
|
warp::reply::json(&Visits {
|
|
|
|
visits: count,
|
|
|
|
since: start,
|
|
|
|
})
|
2022-12-03 02:12:13 +00:00
|
|
|
}
|
|
|
|
|
2023-03-20 21:53:50 +00:00
|
|
|
#[allow(opaque_hidden_inferred_bound)]
|
2022-12-03 02:12:13 +00:00
|
|
|
fn routes(base: Arc<RwLock<Base>>) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone {
|
|
|
|
warp::get().and(
|
|
|
|
warp::path!("powertools" / "v1")
|
|
|
|
.map(move || {
|
|
|
|
let base = base.read().expect("Failed to acquire base limits read lock").clone();
|
|
|
|
get_limits(base)
|
|
|
|
})
|
|
|
|
.or(
|
|
|
|
warp::path!("powertools" / "count")
|
|
|
|
.map(get_visits)
|
|
|
|
)
|
|
|
|
).recover(recovery)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn recovery(reject: warp::Rejection) -> Result<impl warp::Reply, warp::Rejection> {
|
|
|
|
if reject.is_not_found() {
|
|
|
|
Ok(warp::hyper::StatusCode::NOT_FOUND)
|
|
|
|
} else {
|
|
|
|
Err(reject)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
async fn main() {
|
2023-03-20 21:53:50 +00:00
|
|
|
START_TIME.store(chrono::Utc::now().timestamp(), Ordering::Relaxed);
|
2022-12-03 02:12:13 +00:00
|
|
|
let file = std::fs::File::open("./pt_limits.json").expect("Failed to read limits file");
|
|
|
|
let limits: Base = serde_json::from_reader(file).expect("Failed to parse limits file");
|
|
|
|
assert!(limits.refresh.is_some(), "`refresh` cannot be null, since it will brick future refreshes");
|
|
|
|
|
|
|
|
warp::serve(routes(Arc::new(RwLock::new(limits))))
|
|
|
|
.run(([0, 0, 0, 0], 8080))
|
|
|
|
.await;
|
|
|
|
}
|