Setup a server-client program.
I setup a server-client program where the server will terminate when Ctrl+C is pressed.
This commit is contained in:
parent
15ae16abb0
commit
a965f796ae
1546
Cargo.lock
generated
Normal file
1546
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
16
Cargo.toml
16
Cargo.toml
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "satellite"
|
||||
version = "0.0.0"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "Rust Challenge"
|
||||
repository = "/myrddin/satellite"
|
||||
@ -10,4 +10,18 @@ license-file = "LICENSE.md"
|
||||
|
||||
|
||||
|
||||
[[bin]]
|
||||
name = "satellite"
|
||||
path = "src/server.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "base_station"
|
||||
path = "src/client.rs"
|
||||
|
||||
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.5.32", features = ["derive"] }
|
||||
chrono = "0.4.40"
|
||||
tokio = { version = "1.44.1", features = ["macros", "rt-multi-thread", "io-std", "fs", "signal", "sync"] }
|
||||
console-subscriber = "0.4.1"
|
||||
|
@ -1,3 +1,7 @@
|
||||
# satellite
|
||||
# Satellite Propulsion Simulation
|
||||
|
||||
Rust Challenge
|
||||
## Design Approach
|
||||
|
||||
## Instructions
|
||||
### Build
|
||||
### Run
|
||||
|
@ -1,15 +1,15 @@
|
||||
//! Rust Challenge
|
||||
|
||||
|
||||
|
||||
mod project;
|
||||
|
||||
|
||||
/// The environment variable defined by Cargo for the name.
|
||||
const CLIENT_NAME: &'static str = "base_station";
|
||||
|
||||
|
||||
/// Print the version of the project.
|
||||
fn print_version()
|
||||
{
|
||||
println!("{} v{}", project::get_name(), project::get_version());
|
||||
println!("{} v{}", CLIENT_NAME, project::get_version());
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
|
||||
/// The environment variable defined by Cargo for the name.
|
||||
#[allow(dead_code)]
|
||||
const NAME: Option<&str> = option_env!("CARGO_PKG_NAME");
|
||||
|
||||
/// The environment variable defined by Cargo for the version.
|
||||
@ -17,6 +18,7 @@ const NOT_DEFINED: &'static str = "UNDEFINED";
|
||||
/// set at compile time and comes from the Cargo.toml file.
|
||||
///
|
||||
/// If a value is not found, then it will return the not defined value.
|
||||
#[allow(dead_code)]
|
||||
pub fn get_name() -> &'static str
|
||||
{
|
||||
NAME.unwrap_or(NOT_DEFINED)
|
||||
|
84
src/server.rs
Normal file
84
src/server.rs
Normal file
@ -0,0 +1,84 @@
|
||||
//! Rust Challenge: Satellite Propulsion Sim
|
||||
|
||||
mod project;
|
||||
|
||||
|
||||
|
||||
use std::io;
|
||||
|
||||
use tokio::sync::watch;
|
||||
|
||||
|
||||
|
||||
type IoResult<T> = Result<T, io::Error>;
|
||||
|
||||
|
||||
|
||||
/// Print the version of the project.
|
||||
fn print_version()
|
||||
{
|
||||
println!("{} v{}", project::get_name(), project::get_version());
|
||||
}
|
||||
|
||||
/// Asynchronously listen for CTRL-C to be pressed.
|
||||
///
|
||||
/// Sends `false` through the watch channel when the signal is received.
|
||||
async fn listen_for_termination(sender: watch::Sender<bool>) -> IoResult<()>
|
||||
{
|
||||
tokio::signal::ctrl_c().await?;
|
||||
|
||||
println!("\nReceived Ctrl+C, initiating shutdown...");
|
||||
|
||||
// Send termination message to all listeners
|
||||
sender.send_replace(false);
|
||||
sender.closed().await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Program entry point.
|
||||
#[tokio::main]
|
||||
async fn main() -> IoResult<()>
|
||||
{
|
||||
print_version();
|
||||
|
||||
let (term_sender, mut term_receiver) = watch::channel(true);
|
||||
|
||||
// Spawn a task to handle termination signal.
|
||||
let term_task =
|
||||
tokio::spawn(async move { listen_for_termination(term_sender).await });
|
||||
|
||||
// Spawn a task to listen for network communication.
|
||||
let comm_task = tokio::spawn(async move {
|
||||
let mut running = true;
|
||||
while running
|
||||
{
|
||||
tokio::select! {
|
||||
_ = term_receiver.changed() => {
|
||||
println!("Communication task received shutdown message.");
|
||||
running = *term_receiver.borrow_and_update();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Wait for termination signal task and propagate any error.
|
||||
match term_task.await
|
||||
{
|
||||
Ok(Ok(())) =>
|
||||
{}
|
||||
Ok(Err(e)) => return Err(e),
|
||||
Err(e) =>
|
||||
{
|
||||
eprintln!("Termination task panicked: {}", e);
|
||||
return Err(io::Error::new(io::ErrorKind::Other,
|
||||
"Termination task panicked"));
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for the communication task to complete.
|
||||
let _ = comm_task.await;
|
||||
|
||||
println!("Shutdown complete.");
|
||||
Ok(())
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user