improve tracing, use bundled sqlite

This commit is contained in:
41666 2023-06-09 10:42:50 -04:00
parent 3dc0f21b61
commit 019bca8000
5 changed files with 29 additions and 17 deletions

2
Cargo.lock generated
View file

@ -620,6 +620,7 @@ version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326"
dependencies = [
"cc",
"pkg-config",
"vcpkg",
]
@ -688,6 +689,7 @@ dependencies = [
"r2d2",
"r2d2_sqlite",
"reqwest",
"rusqlite",
"serde",
"serde-aux",
"serde_json",

View file

@ -21,4 +21,5 @@ lazy_static = "1.4"
serde-aux = "4"
bincode = "1.3"
r2d2_sqlite = "0.22"
r2d2 = "0.8"
r2d2 = "0.8"
rusqlite = { version = "0.29.0", features = ["bundled"] }

View file

@ -27,7 +27,7 @@ pub async fn get_alerts(world_id: i32) -> Result<Vec<Alert>, ()> {
for world_event in world_events.world_event_list {
let alert = alerts.entry(world_event.id).or_insert(Alert {
id: world_event.metagame_event_id,
id: world_event.id,
zone: world_event.zone_id,
end_time: None,
start_time: None,

View file

@ -10,6 +10,7 @@ use axum::{
use r2d2_sqlite::{rusqlite::params, SqliteConnectionManager};
use std::{env, net::SocketAddr};
use tokio::task::JoinSet;
use tower_http::trace::TraceLayer;
use types::{World, Zone};
use zones::get_zone_states;
@ -22,13 +23,12 @@ mod zones;
#[tokio::main]
async fn main() {
tracing_subscriber::fmt()
// .with_max_level(Level::DEBUG)
.with_env_filter(
tracing_subscriber::EnvFilter::from_default_env()
.add_directive("tower_http=trace".parse().unwrap()),
)
.init();
// let db = sqlite::Connection::open_with_full_mutex(":memory:").unwrap();
// db.execute("CREATE TABLE worlds (id INTEGER NOT NULL PRIMARY KEY, data BLOB);")
// .unwrap();
let sqlite_manager = SqliteConnectionManager::memory();
let pool = r2d2::Pool::new(sqlite_manager).unwrap();
pool.get()
@ -40,21 +40,18 @@ async fn main() {
.unwrap();
let app = Router::new()
.layer(tower_http::trace::TraceLayer::new_for_http())
.route("/:world", get(get_one_world))
.route("/all", get(get_all_worlds))
.route("/", get(root))
.layer(TraceLayer::new_for_http())
.with_state(pool.clone());
tokio::spawn(async move {
loop {
let mut set = JoinSet::new();
for world in vec![1, 10, 13, 17, 19, 40, 1000, 2000] {
set.spawn(get_world(pool.clone(), world, true));
tokio::spawn(get_world(pool.clone(), world, true));
}
while let Some(_) = set.join_next().await {}
tokio::time::sleep(tokio::time::Duration::from_secs(60 * 3)).await;
}
});
@ -103,11 +100,14 @@ pub async fn get_all_worlds(
Json(worlds)
}
#[tracing::instrument(skip(db))]
pub async fn get_world(
db: r2d2::Pool<SqliteConnectionManager>,
world: i32,
skip_cache: bool,
) -> World {
tracing::debug!("Getting world {}", world);
if !skip_cache {
match world_from_cache(db.clone(), world) {
Ok(response) => return response,
@ -141,26 +141,35 @@ pub async fn get_world(
response
}
#[tracing::instrument(skip(db))]
fn world_from_cache(db: r2d2::Pool<SqliteConnectionManager>, world: i32) -> Result<World, ()> {
let db = db.get().unwrap();
let mut query = db.prepare("SELECT data FROM worlds WHERE id = ?").unwrap();
let value: Result<Vec<u8>, _> = query.query_row(params![world], |r| r.get(0));
if value.is_err() {
tracing::debug!("Cache miss (non-exist) for world {}", world);
return Err(());
}
match bincode::deserialize::<World>(value.unwrap().as_slice()) {
Ok(response) => {
if response.cached_at + chrono::Duration::minutes(5) < chrono::Utc::now() {
tracing::debug!("Cache miss (expired) for world {}", world);
return Err(());
}
tracing::debug!("Cache hit for world {}", world);
Ok(response)
}
_ => Err(()),
_ => {
tracing::debug!("Cache miss (corrupt) for world {}", world);
Err(())
}
}
}
#[tracing::instrument(skip(db, response))]
fn world_to_cache(db: r2d2::Pool<SqliteConnectionManager>, world: i32, response: &World) {
let value = bincode::serialize(response).unwrap();
let db = db.get().unwrap();

View file

@ -1,14 +1,14 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize, Clone, Default)]
#[derive(Deserialize, Serialize, Clone, Default, Debug)]
pub struct World {
pub id: i32,
pub zones: Vec<Zone>,
pub cached_at: DateTime<Utc>,
}
#[derive(Deserialize, Serialize, Clone, Default)]
#[derive(Deserialize, Serialize, Clone, Default, Debug)]
pub struct Zone {
pub id: i32,
pub locked: bool,
@ -16,7 +16,7 @@ pub struct Zone {
pub territory: FactionPercents,
}
#[derive(Deserialize, Serialize, Clone, Default)]
#[derive(Deserialize, Serialize, Clone, Default, Debug)]
pub struct Alert {
pub id: i32,
pub zone: i32,
@ -27,7 +27,7 @@ pub struct Alert {
pub percentages: FactionPercents,
}
#[derive(Deserialize, Serialize, Clone, Default)]
#[derive(Deserialize, Serialize, Clone, Default, Debug)]
pub struct FactionPercents {
pub vs: f32,
pub nc: f32,