This commit is contained in:
41666 2022-11-20 16:25:17 -05:00
parent aff10840fd
commit 85e8729261
5 changed files with 74 additions and 7 deletions

32
Cargo.lock generated
View file

@ -36,6 +36,8 @@ dependencies = [
name = "api" name = "api"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"once_cell",
"redis",
"salvo", "salvo",
"serde", "serde",
"serde_json", "serde_json",
@ -133,6 +135,16 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "combine"
version = "4.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4"
dependencies = [
"bytes",
"memchr",
]
[[package]] [[package]]
name = "cookie" name = "cookie"
version = "0.16.1" version = "0.16.1"
@ -757,6 +769,20 @@ dependencies = [
"rand_core", "rand_core",
] ]
[[package]]
name = "redis"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "513b3649f1a111c17954296e4a3b9eecb108b766c803e2b99f179ebe27005985"
dependencies = [
"combine",
"itoa",
"percent-encoding",
"ryu",
"sha1_smol",
"url",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.2.16" version = "0.2.16"
@ -934,6 +960,12 @@ dependencies = [
"digest", "digest",
] ]
[[package]]
name = "sha1_smol"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.7" version = "0.4.7"

View file

@ -70,5 +70,6 @@ This API only supports GET, and supports CORS.
- Serves https://saerro.harasse.rs - Serves https://saerro.harasse.rs
- Redis - Redis
- Using ZADD with score as timestamp, ZCOUNTBYSCORE by timestamp in 15 minute windows, and cleaned up with SCAN+ZREMBYSCORE, population data is tracked. - Using ZADD with score as timestamp, ZCOUNTBYSCORE by timestamp in 15 minute windows, and cleaned up with SCAN+ZREMBYSCORE, population data is tracked.
- There is deliberately no persistence.
- Redis "Tender" - Redis "Tender"
- Cleans up Redis every 5 mins. - Cleans up Redis every 5 mins.

10
docker-compose.yaml Normal file
View file

@ -0,0 +1,10 @@
version: "3"
services:
redis:
image: redis:alpine
command: redis-server --save "" --appendonly no
container_name: redis
restart: always
ports:
- "6379:6379"

View file

@ -10,3 +10,5 @@ salvo = { version = "0.37.4", features = ["cors"] }
tokio = { version = "1.22.0", features = ["macros"] } tokio = { version = "1.22.0", features = ["macros"] }
serde_json = "1.0.88" serde_json = "1.0.88"
serde = "1.0.147" serde = "1.0.147"
redis = "0.22.1"
once_cell = "1.16.0"

View file

@ -1,3 +1,7 @@
use core::time;
use std::{ops::Sub, time::SystemTime};
use once_cell::sync::Lazy;
use salvo::cors::Cors; use salvo::cors::Cors;
use salvo::prelude::*; use salvo::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -29,6 +33,11 @@ struct MultipleWorldPopulation {
worlds: Vec<WorldPopulation>, worlds: Vec<WorldPopulation>,
} }
pub static REDIS_CLIENT: Lazy<redis::Client> = Lazy::new(|| {
redis::Client::open(std::env::var("REDIS_ADDR").unwrap_or("redis://localhost:6379".to_string()))
.unwrap()
});
#[handler] #[handler]
async fn info(req: &mut Request, res: &mut Response) { async fn info(req: &mut Request, res: &mut Response) {
let headers: IncomingHeaders = req.parse_headers().unwrap(); let headers: IncomingHeaders = req.parse_headers().unwrap();
@ -78,14 +87,27 @@ async fn get_world_multi(req: &mut Request, res: &mut Response) {
} }
async fn get_world_pop(world_id: String) -> WorldPopulation { async fn get_world_pop(world_id: String) -> WorldPopulation {
let mut con = REDIS_CLIENT.get_connection().unwrap();
let filter_timestamp = SystemTime::now()
.sub(time::Duration::from_secs(60 * 15))
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs();
let (tr, vs, nc): (u32, u32, u32) = redis::pipe()
.zcount(format!("{}/{}", world_id, 1), filter_timestamp, "+inf")
.zcount(format!("{}/{}", world_id, 2), filter_timestamp, "+inf")
.zcount(format!("{}/{}", world_id, 3), filter_timestamp, "+inf")
.query(&mut con)
.unwrap();
let total = tr + vs + nc;
let response = WorldPopulation { let response = WorldPopulation {
world_id: world_id.parse().unwrap(), world_id: world_id.parse().unwrap(),
total: 0, total,
factions: Factions { factions: Factions { tr, nc, vs },
tr: 0,
nc: 0,
vs: 0,
},
}; };
response response