From 17d8ea0b7fe6abb7151c3b4e6f823592b696f0e6 Mon Sep 17 00:00:00 2001 From: Bryan Stitt Date: Thu, 19 Jan 2023 21:28:33 -0800 Subject: [PATCH] make free tier even better and improve migration locking --- Cargo.lock | 6 +-- README.md | 2 +- entities/Cargo.toml | 2 +- migration/Cargo.toml | 2 +- migration/README.md | 2 +- migration/src/lib.rs | 2 + web3_proxy/Cargo.toml | 2 +- web3_proxy/src/app/mod.rs | 46 ++++++++++++------- .../bin/web3_proxy_cli/drop_migration_lock.rs | 15 ++++-- 9 files changed, 52 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index faf872a6..13f8115b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/README.md b/README.md index 6f2e67c0..9a0ade50 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/entities/Cargo.toml b/entities/Cargo.toml index 16e3ac8e..606a2f39 100644 --- a/entities/Cargo.toml +++ b/entities/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "entities" -version = "0.12.0" +version = "0.13.0" edition = "2021" [lib] diff --git a/migration/Cargo.toml b/migration/Cargo.toml index d1791630..61d25f6d 100644 --- a/migration/Cargo.toml +++ b/migration/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "migration" -version = "0.12.0" +version = "0.13.0" edition = "2021" publish = false diff --git a/migration/README.md b/migration/README.md index b3ea53eb..3b438d89 100644 --- a/migration/README.md +++ b/migration/README.md @@ -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 diff --git a/migration/src/lib.rs b/migration/src/lib.rs index 0f221af2..ca074f18 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -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), ] } } diff --git a/web3_proxy/Cargo.toml b/web3_proxy/Cargo.toml index f1fc8e33..a77e3858 100644 --- a/web3_proxy/Cargo.toml +++ b/web3_proxy/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "web3_proxy" -version = "0.12.0" +version = "0.13.0" edition = "2021" default-run = "web3_proxy_cli" diff --git a/web3_proxy/src/app/mod.rs b/web3_proxy/src/app/mod.rs index 2db6fe52..2e05ace5 100644 --- a/web3_proxy/src/app/mod.rs +++ b/web3_proxy/src/app/mod.rs @@ -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 { - // 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 { + // 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) } diff --git a/web3_proxy/src/bin/web3_proxy_cli/drop_migration_lock.rs b/web3_proxy/src/bin/web3_proxy_cli/drop_migration_lock.rs index 633a0610..ace59c65 100644 --- a/web3_proxy/src/bin/web3_proxy_cli/drop_migration_lock.rs +++ b/web3_proxy/src/bin/web3_proxy_cli/drop_migration_lock.rs @@ -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(()) }