aboutsummaryrefslogtreecommitdiff
path: root/p2p/examples/tokio-example/src
diff options
context:
space:
mode:
Diffstat (limited to 'p2p/examples/tokio-example/src')
-rw-r--r--p2p/examples/tokio-example/src/main.rs80
1 files changed, 80 insertions, 0 deletions
diff --git a/p2p/examples/tokio-example/src/main.rs b/p2p/examples/tokio-example/src/main.rs
new file mode 100644
index 0000000..6a81ac6
--- /dev/null
+++ b/p2p/examples/tokio-example/src/main.rs
@@ -0,0 +1,80 @@
+use std::sync::Arc;
+
+use clap::Parser;
+
+use karyon_p2p::{
+ endpoint::{Endpoint, Port},
+ keypair::{KeyPair, KeyPairType},
+ Backend, Config,
+};
+
+/// Returns an estimate of the default amount of parallelism a program should use.
+/// see `std::thread::available_parallelism`
+pub fn available_parallelism() -> usize {
+ std::thread::available_parallelism()
+ .map(std::num::NonZeroUsize::get)
+ .unwrap_or(1)
+}
+
+#[derive(Parser)]
+#[command(author, version, about, long_about = None)]
+struct Cli {
+ /// Optional list of bootstrap peers to start the seeding process.
+ #[arg(short)]
+ bootstrap_peers: Vec<Endpoint>,
+
+ /// Optional list of peer endpoints for manual connections.
+ #[arg(short)]
+ peer_endpoints: Vec<Endpoint>,
+
+ /// Optional endpoint for accepting incoming connections.
+ #[arg(short)]
+ listen_endpoint: Option<Endpoint>,
+
+ /// Optional TCP/UDP port for the discovery service.
+ #[arg(short)]
+ discovery_port: Option<Port>,
+}
+
+fn main() {
+ env_logger::init();
+ let cli = Cli::parse();
+
+ let key_pair = KeyPair::generate(&KeyPairType::Ed25519);
+
+ // Create the configuration for the backend.
+ let config = Config {
+ listen_endpoint: cli.listen_endpoint,
+ peer_endpoints: cli.peer_endpoints,
+ bootstrap_peers: cli.bootstrap_peers,
+ discovery_port: cli.discovery_port.unwrap_or(0),
+ ..Default::default()
+ };
+
+ // Create a new tokio runtime
+ let rt = Arc::new(
+ tokio::runtime::Builder::new_multi_thread()
+ .worker_threads(available_parallelism())
+ .enable_all()
+ .build()
+ .unwrap(),
+ );
+
+ // Create a new Backend
+ let backend = Backend::new(&key_pair, config, rt.clone().into());
+
+ let (ctrlc_s, ctrlc_r) = async_channel::unbounded();
+ let handle = move || ctrlc_s.try_send(()).unwrap();
+ ctrlc::set_handler(handle).unwrap();
+
+ rt.block_on(async {
+ // Run the backend
+ backend.run().await.unwrap();
+
+ // Wait for ctrlc signal
+ ctrlc_r.recv().await.unwrap();
+
+ // Shutdown the backend
+ backend.shutdown().await;
+ });
+}