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

[transport] Add binding port to SpawnedServer #861

Merged
merged 3 commits into from
Mar 18, 2022

Conversation

patrickkuo
Copy link
Contributor

This is an improvement to SpawnedServer to expose actual binding tcp port, this allow us to start the server with port 0 and retrieve the binding port for later use.

  • add binding port to SpawnedServer
  • cli test use SpawnedServer's binding port instead of hardcoding ports
  • remove wait for "Listening to TCP traffic on 127.0.0.1" log output, start_test_network now block until authorities are up

@patrickkuo patrickkuo force-pushed the pat/config_refactoring branch 2 times, most recently from 625cbe4 to 2c27da9 Compare March 16, 2022 15:09
@patrickkuo patrickkuo force-pushed the pat/spawned_server_port branch from 098f813 to bf957fd Compare March 16, 2022 15:10
Base automatically changed from pat/config_refactoring to main March 16, 2022 16:04
@patrickkuo patrickkuo force-pushed the pat/spawned_server_port branch from bf957fd to d5dc98d Compare March 16, 2022 16:07
@patrickkuo patrickkuo self-assigned this Mar 16, 2022
@patrickkuo patrickkuo marked this pull request as ready for review March 16, 2022 16:08
@patrickkuo patrickkuo force-pushed the pat/spawned_server_port branch from d5dc98d to 866e2a6 Compare March 17, 2022 17:08
Copy link
Contributor

@huitseeker huitseeker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two main things:

  • I think we should expose the whole SocketAddr, we can write the get_port in this PR and we'll deal with e.g. get_address later.
  • We can probably rename things to be closer than what they are:
    • create_network is actually a start_network,
    • start is actually a monitor / wait_for_completion / run_to_end.

network_utils/src/transport.rs Show resolved Hide resolved
tokio::spawn(run_tcp_server(listener, state, receiver, buffer_size))
};
Ok(SpawnedServer { complete, handle })
// see https://fly.io/blog/the-tokio-1-x-upgrade/#tcplistener-from_std-needs-to-be-set-to-nonblocking
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment is too detached from the line it's commenting on.

@@ -86,22 +91,23 @@ where
S: MessageHandler<TcpDataStream> + Send + Sync + 'static,
{
let (complete, receiver) = futures::channel::oneshot::channel();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a cancellation channel, to make this idiiomatic with the rest of the codebase, we could rename (here and in the struct definition), to:

    let (tx_cancellation, rx_cancellation) = futures::channel::oneshot::channel();

let local_addr = std_listener.local_addr()?;
let host = local_addr.ip();
let port = local_addr.port();
info!("Listening to TCP traffic on {}:{}", host, port);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I think captured identifiers are nice.

});
info!("Started {} authorities", handles.len());
join_all(handles).await;
info!("All server stopped.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: plural

}
});
info!("Started {} authorities", handles.len());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the time you log this, these have long been started. You want to log at the end of create_network instead.

Comment on lines 126 to 134
let mut spawned_authorities = Vec::new();
for authority in &config.authorities {
let server = make_server(authority, &committee, config.buffer_size).await?;
spawned_authorities.push(server.spawn().await?);
}
Ok(SuiNetwork {
spawned_authorities,
})
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This create_networknow requires a comment indicating that if we finish the caller's task (and drop the SuiNetwork) without calling start, all servers are dropped as well.

If we drop the SuiNetwork. but not the caller's task, the servers will continue in detached mode (which is probably why the logging-on-error done currently in start should probably be an obligation on the server).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm didn't realise this is behaving this way.... thanks for pointing this out!

In this case I think maybe better moving the create_network into SuiNetwork, so we don't have detached network running unexpectedly.

Comment on lines 669 to 699
let network = create_network(&network_config).await?;

SuiCommand::Genesis {
working_dir,
config: Some(genesis_conf_path),
let network_config = network_config.persisted(&network_path);
network_config.save()?;
keystore.save(&keystore_path)?;

let authorities = network_config.get_authority_infos();
let authorities = authorities
.into_iter()
.zip(&network.spawned_authorities)
.map(|(mut info, server)| {
info.base_port = server.get_port();
info
})
.collect();

// Create wallet.conf with stated authorities port
WalletConfig {
accounts,
keystore: KeystoreType::File(keystore_path),
gateway: GatewayType::Embedded(EmbeddedGatewayConfig {
db_folder_path,
authorities,
..Default::default()
}),
}
.execute()
.await?;
.persisted(&wallet_path)
.save()?;

// Start network
let network = task::spawn(async move {
SuiCommand::Start {
config: network_conf_path,
}
.execute()
.await
});
Ok(network)
Ok(network.start())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The renames I'm suggesting should make this function a lot more understandable: the network is actually started way before start.

Copy link
Contributor

@666lcz 666lcz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love this! The tests are so much cleaner now.

Comment on lines 668 to 633
let (network_config, accounts, keystore) = genesis(genesis_config).await?;
let network = create_network(&network_config).await?;

SuiCommand::Genesis {
working_dir,
config: Some(genesis_conf_path),
let network_config = network_config.persisted(&network_path);
network_config.save()?;
keystore.save(&keystore_path)?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will these files ever get deleted?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we use temp_dir in test, so the folder will get deleted automatically after the test


impl SuiNetwork {
pub fn start(self) -> JoinHandle<Result<(), anyhow::Error>> {
task::spawn(async move {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

N00b question: why do we spawn these spawned_server(which have been spawned on line 129) again?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This extra spawn is redundant! we can wait for completion in the same thread.

.into_iter()
.zip(&network.spawned_authorities)
.map(|(mut info, server)| {
info.base_port = server.get_port();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So how does the non-test code path work? Where do we ensure the port number stored in network.conf matches the one in spawned servers?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in non-test path, if the user decided to start the server using port 0, is their responsibility to manually change the wallet.conf to align the port.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the servers will be spawned using ports provided by network.conf, we will not modify the config to align the port.

When the configured port number is 0, the user can get the actual binding port number from the console/log output.

* cli test use SpawnedServer's binding port instead of hardcoding ports
* remove wait for "Listening to TCP traffic on 127.0.0.1" log output, `start_test_network` now block until authorities are up
@patrickkuo patrickkuo force-pushed the pat/spawned_server_port branch from f3da9b6 to 0cbcc65 Compare March 18, 2022 00:18
@patrickkuo
Copy link
Contributor Author

I have addressed all comments, more review please :)

@patrickkuo patrickkuo requested review from huitseeker and 666lcz March 18, 2022 11:29
Copy link
Contributor

@huitseeker huitseeker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a bunch, with the rename things make much more sense!
So happy we'll now be killing this bug!

@patrickkuo patrickkuo merged commit ec394db into main Mar 18, 2022
@patrickkuo patrickkuo deleted the pat/spawned_server_port branch March 18, 2022 19:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants