Skip to content

shim: add no_retry flag #191

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

Merged
merged 1 commit into from
Jan 22, 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
6 changes: 6 additions & 0 deletions sugondat/shim/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ pub struct SugondatRpcParams {
/// The address of the sugondat-node to connect to.
#[clap(long, default_value = "ws://localhost:9988", env = ENV_SUGONDAT_NODE_URL)]
pub node_url: String,

/// By default the first connection to the node is retried until it is properly connected.
///
/// This flag avoids this behavior by attempting to connect only once
#[clap(long)]
pub no_retry: bool,
}

impl DockParams {
Expand Down
2 changes: 1 addition & 1 deletion sugondat/shim/src/cmd/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ pub async fn run(params: Params) -> anyhow::Result<()> {
async fn connect_rpc(
conn_params: crate::cli::SugondatRpcParams,
) -> anyhow::Result<sugondat_rpc::Client> {
sugondat_rpc::Client::new(conn_params.node_url).await
sugondat_rpc::Client::new(conn_params.node_url, conn_params.no_retry).await
}
6 changes: 3 additions & 3 deletions sugondat/shim/src/cmd/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Pass --submit-dev-alice or --submit-private-key=<..> to fix."
);
}
let server = Server::builder().build(listen_on).await?;
let client = connect_client(&params.rpc.node_url).await?;
let client = connect_client(&params.rpc.node_url, params.rpc.no_retry).await?;
let methods = dock::init(dock::Config {
// TODO: whenever there are more docks, the logic of checking if any at least one is enabled
// and other similar stuff should be in CLI.
Expand All @@ -30,7 +30,7 @@ Pass --submit-dev-alice or --submit-private-key=<..> to fix."
Ok(())
}

async fn connect_client(url: &str) -> anyhow::Result<Client> {
let client = Client::new(url.to_string()).await?;
async fn connect_client(url: &str, no_retry: bool) -> anyhow::Result<Client> {
let client = Client::new(url.to_string(), no_retry).await?;
Ok(client)
}
25 changes: 25 additions & 0 deletions sugondat/shim/src/sugondat_rpc/conn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,31 @@ impl Connector {
}
}

/// Attempt a single connection. Returns the connection handle if successful, otherwise returns the reason for failure
pub async fn try_connect(&self) -> anyhow::Result<Arc<Conn>> {
let mut state = self.state.lock().await;
match &mut *state {
State::Connected(conn) => Ok(conn.clone()),
State::Connecting { .. } => Err(anyhow::anyhow!(
"The connector is already attempting to connect"
)),
State::Disconnected => {
let conn_id = self.gen_conn_id();
let rpc_url = self.rpc_url.clone();
match Conn::connect(conn_id, &rpc_url).await {
Ok(conn) => {
*state = State::Connected(conn.clone());
Ok(conn)
}
Err(e) => Err(anyhow::anyhow!(
"failed to connect to sugondat node: {}\n",
e
)),
}
}
}
}

/// Makes sure that the client is connected. Returns the connection handle.
pub async fn ensure_connected(&self) -> Arc<Conn> {
let mut state = self.state.lock().await;
Expand Down
9 changes: 7 additions & 2 deletions sugondat/shim/src/sugondat_rpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl Client {
/// The RPC URL must be a valid URL pointing to a sugondat node. If it's not a malformed URL,
/// returns an error.
#[tracing::instrument(level = Level::DEBUG)]
pub async fn new(rpc_url: String) -> anyhow::Result<Self> {
pub async fn new(rpc_url: String, no_retry: bool) -> anyhow::Result<Self> {
anyhow::ensure!(
url::Url::parse(&rpc_url).is_ok(),
"invalid RPC URL: {}",
Expand All @@ -50,7 +50,12 @@ impl Client {
let me = Self {
connector: Arc::new(conn::Connector::new(rpc_url)),
};
me.connector.ensure_connected().await;

match no_retry {
true => me.connector.try_connect().await?,
false => me.connector.ensure_connected().await,
};

Ok(me)
}

Expand Down