Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Force db initialization on startup #63

Merged
merged 1 commit into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 24 additions & 1 deletion packages/relayer/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,28 @@ impl Database {
Ok(())
}

pub(crate) async fn test_db_connection(&self) -> Result<()> {
// Try up to 3 times
for i in 1..4 {
match sqlx::query("SELECT 1").execute(&self.db).await {
Ok(_) => {
info!(LOG, "Connected successfully to database");
return Ok(());
}
Err(e) => {
error!(
LOG,
"Failed to initialize connection to the database: {:?}. Retrying...", e
);
tokio::time::sleep(Duration::from_secs(i * i)).await;
}
}
}
Err(anyhow::anyhow!(
"Failed to initialize database connection after 3 attempts"
))
}

pub(crate) async fn get_credentials(&self, account_code: &str) -> Result<Option<Credentials>> {
let row = sqlx::query("SELECT * FROM credentials WHERE account_code = $1")
.bind(account_code)
Expand Down Expand Up @@ -326,6 +348,7 @@ impl Database {
&self,
row: &Request,
) -> std::result::Result<(), DatabaseError> {
let request_id = row.request_id;
let row = sqlx::query(
"INSERT INTO requests (request_id, account_eth_addr, controller_eth_addr, guardian_email_addr, is_for_recovery, template_idx, is_processed, is_success, email_nullifier, account_salt) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING *",
)
Expand All @@ -342,7 +365,7 @@ impl Database {
.fetch_one(&self.db)
.await
.map_err(|e| DatabaseError::new("Failed to insert request", e))?;
info!(LOG, "Request inserted");
info!(LOG, "Request inserted with request_id: {}", request_id);
Ok(())
}
}
32 changes: 21 additions & 11 deletions packages/relayer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub use modules::*;
use relayer_utils::LOG;
pub use strings::*;

use tokio::sync::Mutex;
use tokio::sync::{Mutex, OnceCell};

use anyhow::{anyhow, Result};
use dotenv::dotenv;
Expand All @@ -44,17 +44,27 @@ pub static EMAIL_TEMPLATES: OnceLock<String> = OnceLock::new();
pub static RELAYER_EMAIL_ADDRESS: OnceLock<String> = OnceLock::new();
pub static SMTP_SERVER: OnceLock<String> = OnceLock::new();

static DB_CELL: OnceCell<Arc<Database>> = OnceCell::const_new();

struct DBWrapper;

impl DBWrapper {
fn get() -> &'static Arc<Database> {
DB_CELL.get().expect("Database not initialized")
}
}

impl std::ops::Deref for DBWrapper {
type Target = Database;

fn deref(&self) -> &Self::Target {
&**Self::get()
}
}

static DB: DBWrapper = DBWrapper;

lazy_static! {
pub static ref DB: Arc<Database> = {
dotenv().ok();
let db = tokio::task::block_in_place(|| {
tokio::runtime::Runtime::new()
.unwrap()
.block_on(Database::open(&env::var(DATABASE_PATH_KEY).unwrap()))
})
.unwrap();
Arc::new(db)
};
pub static ref CLIENT: Arc<ChainClient> = {
dotenv().ok();
let client = tokio::task::block_in_place(|| {
Expand Down
17 changes: 17 additions & 0 deletions packages/relayer/src/modules/web_server/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,23 @@ use tower_http::cors::{AllowHeaders, AllowMethods, Any, CorsLayer};
pub async fn run_server() -> Result<()> {
let addr = WEB_SERVER_ADDRESS.get().unwrap();

DB_CELL
.get_or_init(|| async {
dotenv::dotenv().ok();
let db = Database::open(&std::env::var("DATABASE_URL").unwrap())
.await
.unwrap();
Arc::new(db)
})
.await;

info!(LOG, "Testing connection to database");
if let Err(e) = DB.test_db_connection().await {
error!(LOG, "Failed to initialize db with e: {}", e);
panic!("Forcing panic, since connection to DB could not be established");
};
info!(LOG, "Testing connection to database successfull");

let mut app = Router::new()
.route(
"/api/echo",
Expand Down
Loading