From d5bcc971cd1cd3eb718d34d10294ab146d9982b3 Mon Sep 17 00:00:00 2001 From: Josh Stevens Date: Fri, 13 Sep 2024 15:48:02 +0100 Subject: [PATCH] fix: share a postgres instance across rust project --- core/src/generator/build.rs | 12 ++ core/src/generator/database_bindings.rs | 23 ++++ core/src/generator/events_bindings.rs | 10 +- core/src/generator/mod.rs | 2 + documentation/docs/pages/docs/changelog.mdx | 1 + rindexer_rust_playground/rindexer.yaml | 2 +- rindexer_rust_playground/src/main.rs | 111 +++++++++--------- .../src/rindexer_lib/typings/database.rs | 15 +++ .../src/rindexer_lib/typings/mod.rs | 1 + .../events/erc_20_filter.rs | 8 +- .../events/rocket_pool_eth.rs | 12 +- 11 files changed, 129 insertions(+), 68 deletions(-) create mode 100644 core/src/generator/database_bindings.rs create mode 100644 rindexer_rust_playground/src/rindexer_lib/typings/database.rs diff --git a/core/src/generator/build.rs b/core/src/generator/build.rs index 0758dfe2..6fc188ad 100644 --- a/core/src/generator/build.rs +++ b/core/src/generator/build.rs @@ -14,6 +14,7 @@ use super::{ networks_bindings::generate_networks_code, }; use crate::{ + generator::database_bindings::generate_database_code, helpers::{ camel_to_snake, create_mod_file, format_all_files_for_project, write_file, CreateModFileError, WriteFileError, @@ -65,6 +66,13 @@ fn write_global( Ok(()) } +fn write_database(output: &Path) -> Result<(), WriteGlobalError> { + let database_code = generate_database_code(); + write_file(&generate_file_location(output, "database"), database_code.as_str())?; + + Ok(()) +} + #[derive(thiserror::Error, Debug)] pub enum WriteIndexerEvents { #[error("Could not write events code: {0}")] @@ -163,6 +171,10 @@ pub fn generate_rindexer_typings( write_global(&output, global, &manifest.networks)?; } + if manifest.storage.postgres_enabled() { + write_database(&output)?; + } + write_indexer_events(project_path, &output, manifest.to_indexer(), &manifest.storage)?; create_mod_file(output.as_path(), true)?; diff --git a/core/src/generator/database_bindings.rs b/core/src/generator/database_bindings.rs new file mode 100644 index 00000000..ebefc978 --- /dev/null +++ b/core/src/generator/database_bindings.rs @@ -0,0 +1,23 @@ +use crate::types::code::Code; + +pub fn generate_database_code() -> Code { + Code::new( + r#" + use std::sync::Arc; + use rindexer::PostgresClient; + use tokio::sync::OnceCell; + + static POSTGRES_CLIENT: OnceCell> = OnceCell::const_new(); + + pub async fn get_or_init_postgres_client() -> Arc { + POSTGRES_CLIENT + .get_or_init(|| async { + Arc::new(PostgresClient::new().await.expect("Failed to connect to Postgres")) + }) + .await + .clone() + } + "# + .to_string(), + ) +} diff --git a/core/src/generator/events_bindings.rs b/core/src/generator/events_bindings.rs index 56445fd4..25701f7f 100644 --- a/core/src/generator/events_bindings.rs +++ b/core/src/generator/events_bindings.rs @@ -317,7 +317,7 @@ fn generate_event_callback_structs_code( struct_result = info.struct_result(), struct_data = info.struct_data(), database = if databases_enabled { - r#"database: Arc::new(PostgresClient::new().await.expect("Failed to connect to Postgres")),"# + "database: get_or_init_postgres_client().await," } else { "" }, @@ -498,10 +498,11 @@ fn generate_event_bindings_code( contract::{{Contract, ContractDetails}}, yaml::read_manifest, }}, + provider::JsonRpcCachedProvider, {postgres_client_import} - provider::JsonRpcCachedProvider }}; use super::super::super::super::typings::networks::get_provider_cache_for_network; + {postgres_import} {structs} @@ -623,6 +624,11 @@ fn generate_event_bindings_code( }} }} "#, + postgres_import = if storage.postgres_enabled() { + "use super::super::super::super::typings::database::get_or_init_postgres_client;" + } else { + "" + }, postgres_client_import = if storage.postgres_enabled() { "PostgresClient," } else { "" }, csv_import = if storage.csv_enabled() { "AsyncCsvAppender," } else { "" }, abigen_mod_name = abigen_contract_mod_name(contract), diff --git a/core/src/generator/mod.rs b/core/src/generator/mod.rs index 244e3ea4..4b7e86f4 100644 --- a/core/src/generator/mod.rs +++ b/core/src/generator/mod.rs @@ -1,7 +1,9 @@ pub mod build; mod context_bindings; +mod database_bindings; mod docker; mod events_bindings; mod networks_bindings; + pub use docker::generate_docker_file; diff --git a/documentation/docs/pages/docs/changelog.mdx b/documentation/docs/pages/docs/changelog.mdx index e3d45d87..9bcb7501 100644 --- a/documentation/docs/pages/docs/changelog.mdx +++ b/documentation/docs/pages/docs/changelog.mdx @@ -13,6 +13,7 @@ fix: running rust project should only start indexer or graphql passed on args pa fix: resolve issue of paths in generated typings fix: when running rindexer codegen typings csv folder created fix: underscores in events within a rust project maps it wrong in typings +fix: share a postgres instance across rust project ### Breaking changes ------------------------------------------------- diff --git a/rindexer_rust_playground/rindexer.yaml b/rindexer_rust_playground/rindexer.yaml index 1c6619fc..2ee4e41e 100644 --- a/rindexer_rust_playground/rindexer.yaml +++ b/rindexer_rust_playground/rindexer.yaml @@ -26,7 +26,7 @@ contracts: - filter: event_name: Transfer network: ethereum - start_block: 56399431 + #start_block: 56399431 abi: ./abis/erc20-abi.json generate_csv: true global: diff --git a/rindexer_rust_playground/src/main.rs b/rindexer_rust_playground/src/main.rs index d905751c..c828cd99 100644 --- a/rindexer_rust_playground/src/main.rs +++ b/rindexer_rust_playground/src/main.rs @@ -1,6 +1,9 @@ -use std::env; +use std::{env, path::PathBuf, str::FromStr}; -use rindexer::{start_rindexer, GraphqlOverrideSettings, IndexingDetails, StartDetails}; +use rindexer::{ + manifest::yaml::read_manifest, start_rindexer, GraphqlOverrideSettings, IndexingDetails, + StartDetails, +}; use self::rindexer_lib::indexers::all_handlers::register_all_handlers; @@ -78,55 +81,55 @@ async fn main() { } } -// #[allow(dead_code)] -// fn generate() { -// let path = PathBuf::from_str( -// "/Users/joshstevens/code/rindexer/rindexer_rust_playground/rindexer.yaml", -// ) -// .expect("Invalid path"); -// let manifest = read_manifest(&path).expect("Failed to read manifest"); -// rindexer::generator::build::generate_rindexer_typings(&manifest, &path, true) -// .expect("Failed to generate typings"); -// } -// -// #[allow(dead_code)] -// fn generate_code_test() { -// let path = PathBuf::from_str( -// "/Users/joshstevens/code/rindexer/rindexer_rust_playground/rindexer.yaml", -// ) -// .expect("Invalid path"); -// let manifest = read_manifest(&path).expect("Failed to read manifest"); -// -// rindexer::generator::build::generate_rindexer_handlers(manifest, &path, true) -// .expect("Failed to generate handlers"); -// } -// -// #[allow(dead_code)] -// fn generate_all() { -// let path = PathBuf::from_str( -// "/Users/joshstevens/code/rindexer/rindexer_rust_playground/rindexer.yaml", -// ) -// .expect("Invalid path"); -// rindexer::generator::build::generate_rindexer_typings_and_handlers(&path) -// .expect("Failed to generate typings and handlers"); -// } -// -// #[cfg(test)] -// mod tests { -// use super::*; -// -// #[test] -// fn test_generate() { -// generate(); -// } -// -// #[test] -// fn test_code_generate() { -// generate_code_test(); -// } -// -// #[test] -// fn test_generate_all() { -// generate_all(); -// } -// } +#[allow(dead_code)] +fn generate() { + let path = PathBuf::from_str( + "/Users/joshstevens/code/rindexer/rindexer_rust_playground/rindexer.yaml", + ) + .expect("Invalid path"); + let manifest = read_manifest(&path).expect("Failed to read manifest"); + rindexer::generator::build::generate_rindexer_typings(&manifest, &path, true) + .expect("Failed to generate typings"); +} + +#[allow(dead_code)] +fn generate_code_test() { + let path = PathBuf::from_str( + "/Users/joshstevens/code/rindexer/rindexer_rust_playground/rindexer.yaml", + ) + .expect("Invalid path"); + let manifest = read_manifest(&path).expect("Failed to read manifest"); + + rindexer::generator::build::generate_rindexer_handlers(manifest, &path, true) + .expect("Failed to generate handlers"); +} + +#[allow(dead_code)] +fn generate_all() { + let path = PathBuf::from_str( + "/Users/joshstevens/code/rindexer/rindexer_rust_playground/rindexer.yaml", + ) + .expect("Invalid path"); + rindexer::generator::build::generate_rindexer_typings_and_handlers(&path) + .expect("Failed to generate typings and handlers"); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_generate() { + generate(); + } + + #[test] + fn test_code_generate() { + generate_code_test(); + } + + #[test] + fn test_generate_all() { + generate_all(); + } +} diff --git a/rindexer_rust_playground/src/rindexer_lib/typings/database.rs b/rindexer_rust_playground/src/rindexer_lib/typings/database.rs new file mode 100644 index 00000000..d441ad12 --- /dev/null +++ b/rindexer_rust_playground/src/rindexer_lib/typings/database.rs @@ -0,0 +1,15 @@ +use std::sync::Arc; + +use rindexer::PostgresClient; +use tokio::sync::OnceCell; + +static POSTGRES_CLIENT: OnceCell> = OnceCell::const_new(); + +pub async fn get_or_init_postgres_client() -> Arc { + POSTGRES_CLIENT + .get_or_init(|| async { + Arc::new(PostgresClient::new().await.expect("Failed to connect to Postgres")) + }) + .await + .clone() +} diff --git a/rindexer_rust_playground/src/rindexer_lib/typings/mod.rs b/rindexer_rust_playground/src/rindexer_lib/typings/mod.rs index ce2ee456..817ea642 100644 --- a/rindexer_rust_playground/src/rindexer_lib/typings/mod.rs +++ b/rindexer_rust_playground/src/rindexer_lib/typings/mod.rs @@ -1,4 +1,5 @@ #![allow(dead_code, unused)] +pub mod database; pub mod global_contracts; pub mod networks; pub mod rindexer_playground; diff --git a/rindexer_rust_playground/src/rindexer_lib/typings/rindexer_playground/events/erc_20_filter.rs b/rindexer_rust_playground/src/rindexer_lib/typings/rindexer_playground/events/erc_20_filter.rs index 7769144a..431fd787 100644 --- a/rindexer_rust_playground/src/rindexer_lib/typings/rindexer_playground/events/erc_20_filter.rs +++ b/rindexer_rust_playground/src/rindexer_lib/typings/rindexer_playground/events/erc_20_filter.rs @@ -30,7 +30,9 @@ use rindexer::{ AsyncCsvAppender, FutureExt, PostgresClient, }; -use super::super::super::super::typings::networks::get_provider_cache_for_network; +use super::super::super::super::typings::{ + database::get_or_init_postgres_client, networks::get_provider_cache_for_network, +}; /// THIS IS A GENERATED FILE. DO NOT MODIFY MANUALLY. /// /// This file was auto generated by rindexer - https://github.com/joshstevens19/rindexer. @@ -138,9 +140,7 @@ where Self { callback: transfer_handler(closure), context: Arc::new(EventContext { - database: Arc::new( - PostgresClient::new().await.expect("Failed to connect to Postgres"), - ), + database: get_or_init_postgres_client().await, csv: Arc::new(csv), extensions: Arc::new(extensions), }), diff --git a/rindexer_rust_playground/src/rindexer_lib/typings/rindexer_playground/events/rocket_pool_eth.rs b/rindexer_rust_playground/src/rindexer_lib/typings/rindexer_playground/events/rocket_pool_eth.rs index 1de42da1..bdb0480a 100644 --- a/rindexer_rust_playground/src/rindexer_lib/typings/rindexer_playground/events/rocket_pool_eth.rs +++ b/rindexer_rust_playground/src/rindexer_lib/typings/rindexer_playground/events/rocket_pool_eth.rs @@ -30,7 +30,9 @@ use rindexer::{ AsyncCsvAppender, FutureExt, PostgresClient, }; -use super::super::super::super::typings::networks::get_provider_cache_for_network; +use super::super::super::super::typings::{ + database::get_or_init_postgres_client, networks::get_provider_cache_for_network, +}; /// THIS IS A GENERATED FILE. DO NOT MODIFY MANUALLY. /// /// This file was auto generated by rindexer - https://github.com/joshstevens19/rindexer. @@ -140,9 +142,7 @@ where Self { callback: approval_handler(closure), context: Arc::new(EventContext { - database: Arc::new( - PostgresClient::new().await.expect("Failed to connect to Postgres"), - ), + database: get_or_init_postgres_client().await, csv: Arc::new(csv), extensions: Arc::new(extensions), }), @@ -243,9 +243,7 @@ where Self { callback: transfer_handler(closure), context: Arc::new(EventContext { - database: Arc::new( - PostgresClient::new().await.expect("Failed to connect to Postgres"), - ), + database: get_or_init_postgres_client().await, csv: Arc::new(csv), extensions: Arc::new(extensions), }),