mapserver: serve old files before regen

This commit is contained in:
Pascal Engélibert 2022-08-19 23:43:41 +02:00
parent bc7e9629c1
commit 61d8267bf5
3 changed files with 350 additions and 271 deletions

571
mapserver/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -4,14 +4,14 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
async-std = { version = "1.6.5", features = ["attributes"] } async-std = { version = "1.12.0", features = ["attributes"] }
clap = { version = "3.1.1", default-features = false, features = ["derive", "std"] } clap = { version = "3.2.17", default-features = false, features = ["derive", "std"] }
crossbeam-channel = "0.5.2" crossbeam-channel = "0.5.6"
directories = "4.0.0" directories = "4.0.1"
http-types = "2.12.0" http-types = "2.12.0"
image = { version = "0.24.1", default-features = false, features = ["png"] } image = { version = "0.24.3", default-features = false, features = ["png"] }
log = "0.4.14" log = "0.4.17"
parking_lot = "0.12.0" parking_lot = "0.12.1"
serde = "1.0.117" serde = "1.0.143"
simplelog = "0.11.1" simplelog = "0.12.0"
tide = "0.16.0" tide = "0.16.0"

View File

@ -1,7 +1,5 @@
#![feature(try_blocks)] #![feature(try_blocks)]
//mod config;
use clap::Parser; use clap::Parser;
use crossbeam_channel::Sender; use crossbeam_channel::Sender;
use log::{debug, error, info, warn}; use log::{debug, error, info, warn};
@ -157,6 +155,7 @@ fn generate_tile(
tile_path: &str, tile_path: &str,
tasks: Arc<RwLock<HashMap<(i32, i32, i32), Sender<()>>>>, tasks: Arc<RwLock<HashMap<(i32, i32, i32), Sender<()>>>>,
config: Arc<Args>, config: Arc<Args>,
must_wait: bool,
) -> Result<(), Error> { ) -> Result<(), Error> {
let mut generate = true; let mut generate = true;
loop { loop {
@ -164,6 +163,9 @@ fn generate_tile(
if let Some(sender) = tasks_guard.get(&(z, x, y)) { if let Some(sender) = tasks_guard.get(&(z, x, y)) {
let sender = sender.clone(); let sender = sender.clone();
drop(tasks_guard); drop(tasks_guard);
if !must_wait {
return Ok(());
}
generate = false; generate = false;
sender.send(()).ok(); sender.send(()).ok();
} else { } else {
@ -387,12 +389,12 @@ fn get_dep_tile(
.unwrap() .unwrap()
.as_secs() > config.cache_age .as_secs() > config.cache_age
{ {
generate_tile(z, x, y, &tile_dir, &tile_path, tasks, config)?; generate_tile(z, x, y, &tile_dir, &tile_path, tasks, config, true)?;
} }
} }
Err(e) => { Err(e) => {
warn!("Cannot get modified time of `{}`: {}", tile_path, e); warn!("Cannot get modified time of `{}`: {}", tile_path, e);
generate_tile(z, x, y, &tile_dir, &tile_path, tasks, config)?; generate_tile(z, x, y, &tile_dir, &tile_path, tasks, config, true)?;
} }
}, },
Err(e) => { Err(e) => {
@ -401,7 +403,7 @@ fn get_dep_tile(
} else { } else {
warn!("Cannot get metadata of `{}`: {}", tile_path, e); warn!("Cannot get metadata of `{}`: {}", tile_path, e);
} }
generate_tile(z, x, y, &tile_dir, &tile_path, tasks, config)?; generate_tile(z, x, y, &tile_dir, &tile_path, tasks, config, true)?;
} }
} }
Ok(tile_path) Ok(tile_path)
@ -416,10 +418,26 @@ fn resp_tile(
tasks: Arc<RwLock<HashMap<(i32, i32, i32), Sender<()>>>>, tasks: Arc<RwLock<HashMap<(i32, i32, i32), Sender<()>>>>,
config: Arc<Args>, config: Arc<Args>,
) -> Result<Vec<u8>, Error> { ) -> Result<Vec<u8>, Error> {
generate_tile(z, x, y, tile_dir, tile_path, tasks, config)?; generate_tile(z, x, y, tile_dir, tile_path, tasks, config, true)?;
read_tile_file(tile_path) read_tile_file(tile_path)
} }
fn resp_old_tile_then_gen(
z: i32,
x: i32,
y: i32,
tile_dir: String,
tile_path: String,
tasks: Arc<RwLock<HashMap<(i32, i32, i32), Sender<()>>>>,
config: Arc<Args>,
) -> Result<Vec<u8>, Error> {
let tile = read_tile_file(&tile_path);
std::thread::spawn(move || {
generate_tile(z, x, y, &tile_dir, &tile_path, tasks, config, false).ok();
});
tile
}
async fn req_tile( async fn req_tile(
req: Request<()>, req: Request<()>,
tasks: Arc<RwLock<HashMap<(i32, i32, i32), Sender<()>>>>, tasks: Arc<RwLock<HashMap<(i32, i32, i32), Sender<()>>>>,
@ -446,7 +464,7 @@ async fn req_tile(
.unwrap() .unwrap()
.as_secs() > config.cache_age .as_secs() > config.cache_age
{ {
match resp_tile(z, x, y, &tile_dir, &tile_path, tasks, config) { match resp_old_tile_then_gen(z, x, y, tile_dir, tile_path, tasks, config) {
Ok(tile_content) => Ok(tide::Response::builder(200) Ok(tile_content) => Ok(tide::Response::builder(200)
.content_type(http_types::mime::PNG) .content_type(http_types::mime::PNG)
.body(tile_content) .body(tile_content)