Add retry mechanism to connect to PostgreSQL before starting maplibre (#1539)

This commit is contained in:
Theo 2024-10-21 14:41:48 +07:00
parent 6f201fcf69
commit 953f23f674
3 changed files with 28 additions and 2 deletions

12
Cargo.lock generated
View File

@ -2544,6 +2544,7 @@ dependencies = [
"tilejson",
"tokio",
"tokio-postgres-rustls",
"tokio-retry",
"url",
]
@ -4948,6 +4949,17 @@ dependencies = [
"x509-cert",
]
[[package]]
name = "tokio-retry"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f"
dependencies = [
"pin-project",
"rand",
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.26.0"

View File

@ -113,6 +113,7 @@ tilejson.workspace = true
tokio = { workspace = true, features = ["io-std"] }
tokio-postgres-rustls = { workspace = true, optional = true }
url.workspace = true
tokio-retry = "0.3.0"
[build-dependencies]
static-files = { workspace = true, optional = true }

View File

@ -15,7 +15,9 @@ use crate::pg::utils::on_slow;
use crate::pg::PgResult;
use crate::source::TileInfoSources;
use crate::utils::{IdResolver, OptBoolObj, OptOneMany};
use crate::MartinResult;
use crate::{MartinError, MartinResult};
use tokio_retry::strategy::{jitter, FixedInterval};
use tokio_retry::Retry;
pub trait PgInfo {
fn format_id(&self) -> String;
@ -114,7 +116,18 @@ impl PgConfig {
}
pub async fn resolve(&mut self, id_resolver: IdResolver) -> MartinResult<TileInfoSources> {
let pg = PgBuilder::new(self, id_resolver).await?;
// Retry strategy: Fixed 5 seconds interval backoff with jitter (random variation)
let retry_strategy = FixedInterval::from_millis(5000)
.map(jitter) // Add random jitter to avoid "thundering herd" problem
.take(3); // Retry up to 3 times
// Create PgBuilder using retry_strategy
let pg = Retry::spawn(retry_strategy, || async {
PgBuilder::new(self, id_resolver.clone()).await
})
.await
.map_err(MartinError::PostgresError)?;
let inst_tables = on_slow(
pg.instantiate_tables(),
// warn only if default bounds timeout has already passed