Skip to content

Commit ef87d5d

Browse files
authored
upstream(graphql): deduplicate configs and clap args, add flag to skip db compatibility (#9261)
# Description of change Original descriptions: > Avoid duplicating fields for configs that are accepted as flags from the command-line and can also be read from TOML file. Use the same struct for both purposes but deocrate it with both clap and serde (or GraphQLConfig) annotations so that it can serve both purposes. > Add a flag to optionally skip database migration compatibility checks. This is helpful when trying to connect a local build up to a production database to test a specific change, even if you are aware that other queries may not be compatible. To accommodate this change, the compatibility check was also moved into `ServerBuilder` where the config is readily available. This also slightly simplifies the `Server` itself, which no longer needs to hold onto its own instance of the `Db`. ## Links to any relevant issues fixes #9217 ## How the change has been tested Comparing `cargo run --bin iota-graphql-rpc -- start-server --help` before and after the change. - [x] Basic tests (linting, compilation, formatting, unit/integration tests) - [ ] Patch-specific tests (correctness, functionality coverage) ### Infrastructure QA (only required for crates that are maintained by @iotaledger/infrastructure) - [ ] Synchronization of the indexer from genesis for a network including migration objects. - [ ] Restart of indexer synchronization locally without resetting the database. - [ ] Restart of indexer synchronization on a production-like database. - [x] Deployment of services using Docker. - Tested if graphql starts up successfully with `pg-services-local` - [ ] Verification of API backward compatibility.
2 parents e5eb616 + e42a64c commit ef87d5d

File tree

6 files changed

+67
-83
lines changed

6 files changed

+67
-83
lines changed

crates/iota-cluster-test/src/cluster.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ impl Cluster for LocalNewCluster {
275275
None,
276276
None,
277277
None,
278+
None,
278279
);
279280

280281
start_graphql_server_with_fn_rpc(

crates/iota-graphql-rpc/src/commands.rs

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use std::path::PathBuf;
66

77
use clap::*;
88

9+
use crate::config::{ConnectionConfig, Ide, TxExecFullNodeConfig};
10+
911
#[derive(Parser)]
1012
#[command(name = "iota-graphql-rpc", about = "IOTA GraphQL RPC", author)]
1113
pub enum Command {
@@ -21,34 +23,17 @@ pub enum Command {
2123
file: Option<PathBuf>,
2224
},
2325
StartServer {
24-
/// The title to display at the top of the page
25-
#[arg(short, long)]
26-
ide_title: Option<String>,
27-
/// DB URL for data fetching
28-
#[arg(short, long)]
29-
db_url: Option<String>,
30-
/// Pool size for DB connections
31-
#[arg(long)]
32-
db_pool_size: Option<u32>,
33-
/// Port to bind the server to
34-
#[arg(short, long)]
35-
port: Option<u16>,
36-
/// Host to bind the server to
37-
#[arg(long)]
38-
host: Option<String>,
39-
/// Port to bind the prom server to
40-
#[arg(long)]
41-
prom_port: Option<u16>,
42-
/// Host to bind the prom server to
43-
#[arg(long)]
44-
prom_host: Option<String>,
26+
#[command(flatten)]
27+
ide: Ide,
28+
29+
#[command(flatten)]
30+
connection: ConnectionConfig,
4531

4632
/// Path to TOML file containing configuration for service.
4733
#[arg(short, long)]
4834
config: Option<PathBuf>,
4935

50-
/// RPC url to the Node for tx execution
51-
#[arg(long)]
52-
node_rpc_url: Option<String>,
36+
#[command(flatten)]
37+
tx_exec_full_node: TxExecFullNodeConfig,
5338
},
5439
}

crates/iota-graphql-rpc/src/config.rs

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,30 @@ pub struct ServerConfig {
3131
/// other services, and might differ from instance to instance of the GraphQL
3232
/// service.
3333
#[GraphQLConfig]
34-
#[derive(Clone, Eq, PartialEq)]
34+
#[derive(clap::Args, Clone, Eq, PartialEq)]
3535
pub struct ConnectionConfig {
3636
/// Port to bind the server to
37-
pub(crate) port: u16,
37+
#[arg(short, long, default_value_t = ConnectionConfig::default().port)]
38+
pub port: u16,
3839
/// Host to bind the server to
39-
pub(crate) host: String,
40-
pub(crate) db_url: String,
41-
pub(crate) db_pool_size: u32,
42-
pub(crate) prom_url: String,
43-
pub(crate) prom_port: u16,
40+
#[arg(long, default_value_t = ConnectionConfig::default().host)]
41+
pub host: String,
42+
/// DB URL for data fetching
43+
#[arg(short, long, default_value_t = ConnectionConfig::default().db_url)]
44+
pub db_url: String,
45+
/// Pool size for DB connections
46+
#[arg(long, default_value_t = ConnectionConfig::default().db_pool_size)]
47+
pub db_pool_size: u32,
48+
/// Host to bind the prom server to
49+
#[arg(long, default_value_t = ConnectionConfig::default().prom_host)]
50+
pub prom_host: String,
51+
/// Port to bind the prom server to
52+
#[arg(long, default_value_t = ConnectionConfig::default().prom_port)]
53+
pub prom_port: u16,
54+
/// Skip checking whether the service is compatible with the DB it is about
55+
/// to connect to, on start-up.
56+
#[arg(long, default_value_t = ConnectionConfig::default().skip_migration_consistency_check)]
57+
pub skip_migration_consistency_check: bool,
4458
}
4559

4660
/// Configuration on features supported by the GraphQL service, passed in a
@@ -162,7 +176,10 @@ impl Version {
162176
}
163177

164178
#[GraphQLConfig]
179+
#[derive(clap::Args)]
165180
pub struct Ide {
181+
/// The title to display at the top of the web-based GraphiQL IDE.
182+
#[arg(short, long, default_value_t = Ide::default().ide_title)]
166183
pub(crate) ide_title: String,
167184
}
168185

@@ -189,8 +206,10 @@ pub struct InternalFeatureConfig {
189206
}
190207

191208
#[GraphQLConfig]
192-
#[derive(Default)]
209+
#[derive(clap::Args, Default)]
193210
pub struct TxExecFullNodeConfig {
211+
/// RPC URL for the fullnode to send transactions to execute and dry-run.
212+
#[arg(long)]
194213
pub(crate) node_rpc_url: Option<String>,
195214
}
196215

@@ -339,29 +358,26 @@ impl ServiceConfig {
339358
}
340359
}
341360

342-
impl TxExecFullNodeConfig {
343-
pub fn new(node_rpc_url: Option<String>) -> Self {
344-
Self { node_rpc_url }
345-
}
346-
}
347-
348361
impl ConnectionConfig {
349362
pub fn new(
350363
port: Option<u16>,
351364
host: Option<String>,
352365
db_url: Option<String>,
353366
db_pool_size: Option<u32>,
354-
prom_url: Option<String>,
367+
prom_host: Option<String>,
355368
prom_port: Option<u16>,
369+
skip_migration_consistency_check: Option<bool>,
356370
) -> Self {
357371
let default = Self::default();
358372
Self {
359373
port: port.unwrap_or(default.port),
360374
host: host.unwrap_or(default.host),
361375
db_url: db_url.unwrap_or(default.db_url),
362376
db_pool_size: db_pool_size.unwrap_or(default.db_pool_size),
363-
prom_url: prom_url.unwrap_or(default.prom_url),
377+
prom_host: prom_host.unwrap_or(default.prom_host),
364378
prom_port: prom_port.unwrap_or(default.prom_port),
379+
skip_migration_consistency_check: skip_migration_consistency_check
380+
.unwrap_or(default.skip_migration_consistency_check),
365381
}
366382
}
367383

@@ -431,14 +447,6 @@ impl Limits {
431447
}
432448
}
433449

434-
impl Ide {
435-
pub fn new(ide_title: Option<String>) -> Self {
436-
ide_title
437-
.map(|ide_title| Ide { ide_title })
438-
.unwrap_or_default()
439-
}
440-
}
441-
442450
impl BackgroundTasksConfig {
443451
pub fn test_defaults() -> Self {
444452
Self {
@@ -474,8 +482,9 @@ impl Default for ConnectionConfig {
474482
host: "127.0.0.1".to_string(),
475483
db_url: "postgres://postgres:postgrespw@localhost:5432/iota_indexer".to_string(),
476484
db_pool_size: 10,
477-
prom_url: "0.0.0.0".to_string(),
485+
prom_host: "0.0.0.0".to_string(),
478486
prom_port: 9184,
487+
skip_migration_consistency_check: false,
479488
}
480489
}
481490
}

crates/iota-graphql-rpc/src/main.rs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::{fs, path::PathBuf};
77
use clap::{CommandFactory, FromArgMatches};
88
use iota_graphql_rpc::{
99
commands::Command,
10-
config::{ConnectionConfig, Ide, ServerConfig, ServiceConfig, TxExecFullNodeConfig, Version},
10+
config::{ServerConfig, ServiceConfig, Version},
1111
server::{builder::export_schema, graphiql_server::start_graphiql_server},
1212
};
1313
use tokio_util::{sync::CancellationToken, task::TaskTracker};
@@ -51,18 +51,11 @@ async fn main() {
5151
}
5252
}
5353
Command::StartServer {
54-
ide_title,
55-
db_url,
56-
db_pool_size,
57-
port,
58-
host,
54+
ide,
55+
connection,
5956
config,
60-
node_rpc_url,
61-
prom_host,
62-
prom_port,
57+
tx_exec_full_node,
6358
} => {
64-
let connection =
65-
ConnectionConfig::new(port, host, db_url, db_pool_size, prom_host, prom_port);
6659
let service_config = service_config(config);
6760
let _guard = telemetry_subscribers::TelemetryConfig::new()
6861
.with_env()
@@ -74,8 +67,8 @@ async fn main() {
7467
let server_config = ServerConfig {
7568
connection,
7669
service: service_config,
77-
ide: Ide::new(ide_title),
78-
tx_exec_full_node: TxExecFullNodeConfig::new(node_rpc_url),
70+
ide,
71+
tx_exec_full_node,
7972
..ServerConfig::default()
8073
};
8174

crates/iota-graphql-rpc/src/server/builder.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ pub(crate) struct Server {
9494
system_package_task: SystemPackageTask,
9595
trigger_exchange_rates_task: TriggerExchangeRatesTask,
9696
state: AppState,
97-
db_reader: Db,
9897
}
9998

10099
impl Server {
@@ -104,14 +103,6 @@ impl Server {
104103
pub async fn run(mut self) -> Result<(), Error> {
105104
get_or_init_server_start_time().await;
106105

107-
{
108-
// Compatibility check
109-
info!("Starting compatibility check");
110-
let mut connection = get_pool_connection(&self.db_reader.inner.get_pool())?;
111-
check_db_migration_consistency(&mut connection)?;
112-
info!("Compatibility check passed");
113-
}
114-
115106
// A handle that spawns a background task to periodically update the
116107
// `Watermark`, which consists of the checkpoint upper bound and current
117108
// epoch.
@@ -364,7 +355,7 @@ impl ServerBuilder {
364355
);
365356

366357
let trigger_exchange_rates_task = TriggerExchangeRatesTask::new(
367-
db_reader.clone(),
358+
db_reader,
368359
watermark_task.epoch_receiver(),
369360
state.cancellation_token.clone(),
370361
);
@@ -391,7 +382,6 @@ impl ServerBuilder {
391382
system_package_task,
392383
trigger_exchange_rates_task,
393384
state,
394-
db_reader,
395385
})
396386
}
397387

@@ -405,13 +395,13 @@ impl ServerBuilder {
405395
// PROMETHEUS
406396
let prom_addr: SocketAddr = format!(
407397
"{}:{}",
408-
config.connection.prom_url, config.connection.prom_port
398+
config.connection.prom_host, config.connection.prom_port
409399
)
410400
.parse()
411401
.map_err(|_| {
412402
Error::Internal(format!(
413403
"Failed to parse url {}, port {} into socket address",
414-
config.connection.prom_url, config.connection.prom_port
404+
config.connection.prom_host, config.connection.prom_port
415405
))
416406
})?;
417407

@@ -450,6 +440,14 @@ impl ServerBuilder {
450440
)
451441
.map_err(|e| Error::ServerInit(format!("Failed to create pg connection pool: {e}")))?;
452442

443+
if !config.connection.skip_migration_consistency_check {
444+
// Compatibility check
445+
info!("Starting compatibility check");
446+
let mut connection = get_pool_connection(&reader.get_pool())?;
447+
check_db_migration_consistency(&mut connection)?;
448+
info!("Compatibility check passed");
449+
}
450+
453451
// DB
454452
let db = Db::new(
455453
reader.clone(),

crates/iota/src/iota_commands.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -906,14 +906,12 @@ async fn start(
906906
let graphql_address = parse_host_port(input, DEFAULT_GRAPHQL_PORT)
907907
.map_err(|_| anyhow!("Invalid graphql host and port"))?;
908908
tracing::info!("Starting the GraphQL service at {graphql_address}");
909-
let graphql_connection_config = ConnectionConfig::new(
910-
Some(graphql_address.port()),
911-
Some(graphql_address.ip().to_string()),
912-
Some(pg_address),
913-
None,
914-
None,
915-
None,
916-
);
909+
let graphql_connection_config = ConnectionConfig {
910+
port: graphql_address.port(),
911+
host: graphql_address.ip().to_string(),
912+
db_url: pg_address,
913+
..Default::default()
914+
};
917915
start_graphql_server_with_fn_rpc(
918916
graphql_connection_config,
919917
Some(fullnode_url.clone()),

0 commit comments

Comments
 (0)