make free tier even better and improve migration locking

This commit is contained in:
Bryan Stitt 2023-01-19 21:28:33 -08:00
parent 0731d92dec
commit 17d8ea0b7f
9 changed files with 52 additions and 27 deletions

6
Cargo.lock generated

@ -1355,7 +1355,7 @@ dependencies = [
[[package]]
name = "entities"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"ethers",
"sea-orm",
@ -2746,7 +2746,7 @@ dependencies = [
[[package]]
name = "migration"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"sea-orm-migration",
"tokio",
@ -5565,7 +5565,7 @@ dependencies = [
[[package]]
name = "web3_proxy"
version = "0.12.0"
version = "0.13.0"
dependencies = [
"anyhow",
"arc-swap",

@ -104,7 +104,7 @@ web3_proxy_cli --config ... change_user_tier_by_key "$RPC_ULID_KEY_FROM_PREV_COM
Health check 3 servers and error if the first one doesn't match the others.
```
web3_proxy_cli https://eth.llamarpc.com/ https://rpc.ankr.com/eth https://cloudflare-eth.com
web3_proxy_cli health_compass https://eth.llamarpc.com/ https://rpc.ankr.com/eth https://cloudflare-eth.com
```
## Adding new database tables

@ -1,6 +1,6 @@
[package]
name = "entities"
version = "0.12.0"
version = "0.13.0"
edition = "2021"
[lib]

@ -1,6 +1,6 @@
[package]
name = "migration"
version = "0.12.0"
version = "0.13.0"
edition = "2021"
publish = false

@ -2,7 +2,7 @@
- Generate a new migration file
```sh
cargo run -- migrate generate MIGRATION_NAME
cargo run -- generate MIGRATION_NAME
```
- Apply all pending migrations
```sh

@ -12,6 +12,7 @@ mod m20221101_222349_archive_request;
mod m20221108_200345_save_anon_stats;
mod m20221211_124002_request_method_privacy;
mod m20221213_134158_move_login_into_database;
mod m20230119_204135_better_free_tier;
pub struct Migrator;
@ -31,6 +32,7 @@ impl MigratorTrait for Migrator {
Box::new(m20221108_200345_save_anon_stats::Migration),
Box::new(m20221211_124002_request_method_privacy::Migration),
Box::new(m20221213_134158_move_login_into_database::Migration),
Box::new(m20230119_204135_better_free_tier::Migration),
]
}
}

@ -1,6 +1,6 @@
[package]
name = "web3_proxy"
version = "0.12.0"
version = "0.13.0"
edition = "2021"
default-run = "web3_proxy_cli"

@ -273,18 +273,14 @@ pub async fn drop_migration_lock(db_conn: &DatabaseConnection) -> Result<(), DbE
Ok(())
}
/// Connect to the database and run migrations
pub async fn get_migrated_db(
db_url: String,
min_connections: u32,
max_connections: u32,
) -> anyhow::Result<DatabaseConnection> {
// TODO: this seems to fail silently
let db_conn = get_db(db_url, min_connections, max_connections).await?;
/// Be super careful with override_existing_lock! It is very important that only one process is running the migrations at a time!
pub async fn migrate_db(
db_conn: &DatabaseConnection,
override_existing_lock: bool,
) -> Result<(), DbErr> {
let db_backend = db_conn.get_database_backend();
// TODO: put the timestamp into this?
// TODO: put the timestamp and hostname into this as columns?
let create_lock_statment = db_backend.build(
Table::create()
.table(Alias::new("migration_lock"))
@ -294,18 +290,24 @@ pub async fn get_migrated_db(
loop {
if Migrator::get_pending_migrations(&db_conn).await?.is_empty() {
info!("no migrations to apply");
return Ok(db_conn);
return Ok(());
}
// there are migrations to apply
// acquire a lock
if let Err(err) = db_conn.execute(create_lock_statment.clone()).await {
debug!("Unable to acquire lock. err={:?}", err);
if override_existing_lock {
warn!("OVERRIDING EXISTING LOCK in 10 seconds! ctrl+c now if other migrations are actually running!");
// TODO: exponential backoff with jitter
sleep(Duration::from_secs(1)).await;
sleep(Duration::from_secs(10)).await
} else {
debug!("Unable to acquire lock. if you are positive no migration is running, run \"web3_proxy_cli drop_migration_lock\". err={:?}", err);
continue;
// TODO: exponential backoff with jitter?
sleep(Duration::from_secs(1)).await;
continue;
}
}
debug!("migration lock acquired");
@ -318,7 +320,19 @@ pub async fn get_migrated_db(
drop_migration_lock(&db_conn).await?;
// return if migrations erred
migration_result?;
migration_result
}
/// Connect to the database and run migrations
pub async fn get_migrated_db(
db_url: String,
min_connections: u32,
max_connections: u32,
) -> Result<DatabaseConnection, DbErr> {
// TODO: this seems to fail silently
let db_conn = get_db(db_url, min_connections, max_connections).await?;
migrate_db(&db_conn, false).await?;
Ok(db_conn)
}

@ -1,15 +1,24 @@
use argh::FromArgs;
use migration::sea_orm::DatabaseConnection;
use web3_proxy::app::drop_migration_lock;
use web3_proxy::app::{drop_migration_lock, migrate_db};
#[derive(FromArgs, PartialEq, Debug, Eq)]
/// In case of emergency, break glass.
#[argh(subcommand, name = "drop_migration_lock")]
pub struct DropMigrationLockSubCommand {}
pub struct DropMigrationLockSubCommand {
#[argh(option)]
/// run migrations after dropping the lock
and_migrate: bool,
}
impl DropMigrationLockSubCommand {
pub async fn main(&self, db_conn: &DatabaseConnection) -> anyhow::Result<()> {
drop_migration_lock(db_conn).await?;
if self.and_migrate {
migrate_db(db_conn, true).await?;
} else {
// just drop the lock
drop_migration_lock(db_conn).await?;
}
Ok(())
}