Just pushing everything in for backup.
This commit is contained in:
parent
64720ab226
commit
6a9bc09be3
261
Cargo.lock
generated
Normal file
261
Cargo.lock
generated
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "addr2line"
|
||||||
|
version = "0.24.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
|
||||||
|
dependencies = [
|
||||||
|
"gimli",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "adler2"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "backtrace"
|
||||||
|
version = "0.3.75"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002"
|
||||||
|
dependencies = [
|
||||||
|
"addr2line",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"miniz_oxide",
|
||||||
|
"object",
|
||||||
|
"rustc-demangle",
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytes"
|
||||||
|
version = "1.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gimli"
|
||||||
|
version = "0.31.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.172"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miniz_oxide"
|
||||||
|
version = "0.8.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
|
||||||
|
dependencies = [
|
||||||
|
"adler2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "object"
|
||||||
|
version = "0.36.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-lite"
|
||||||
|
version = "0.2.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.95"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.40"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-demangle"
|
||||||
|
version = "0.1.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "satellite"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.101"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio"
|
||||||
|
version = "1.45.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165"
|
||||||
|
dependencies = [
|
||||||
|
"backtrace",
|
||||||
|
"bytes",
|
||||||
|
"libc",
|
||||||
|
"mio",
|
||||||
|
"pin-project-lite",
|
||||||
|
"signal-hook-registry",
|
||||||
|
"tokio-macros",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-macros"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm",
|
||||||
|
"windows_aarch64_msvc",
|
||||||
|
"windows_i686_gnu",
|
||||||
|
"windows_i686_gnullvm",
|
||||||
|
"windows_i686_msvc",
|
||||||
|
"windows_x86_64_gnu",
|
||||||
|
"windows_x86_64_gnullvm",
|
||||||
|
"windows_x86_64_msvc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
@ -11,3 +11,4 @@ license-file = "LICENSE.md"
|
|||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
tokio = { version = "1.44.1", features = ["macros", "rt-multi-thread", "io-std", "io-util", "time", "signal", "sync"] }
|
||||||
|
64
docs/problem_statement.md
Normal file
64
docs/problem_statement.md
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# Problem Statement
|
||||||
|
You are a member of the flight software team at Umbra and are responsible
|
||||||
|
for writing code that manages the satellite’s propulsion system.
|
||||||
|
|
||||||
|
Firing the propulsion system involves waiting for a certain period of time before ignition.
|
||||||
|
|
||||||
|
The following is an example usage of this system:
|
||||||
|
|
||||||
|
* At absolute time t = 0, send a command to the computer to fire the propulsion in 15 seconds
|
||||||
|
* At absolute time t = 2, send a command to the computer to fire the propulsion in 30 seconds
|
||||||
|
* At absolute time t = 32, the computer begins firing the propulsion
|
||||||
|
|
||||||
|
The flight computer should accept a command with a relative time of when to fire
|
||||||
|
the propulsion - once that time has elapsed, the program should print out “firing now!”.
|
||||||
|
If another command is received before the propulsion is fired then the most recently
|
||||||
|
received relative time should overwrite any existing commands.
|
||||||
|
|
||||||
|
More formally, if a command _A_ is waiting to fire and another command _B_ is received
|
||||||
|
before A has fired, then B should replace _A_ as the pending command and _A_ should never fire.
|
||||||
|
|
||||||
|
If a time of -1 is given, any outstanding commands to fire the propulsion are cancelled.
|
||||||
|
|
||||||
|
Note that the flight computer should be able to fire the thruster multiple times in a
|
||||||
|
single execution of the program.
|
||||||
|
|
||||||
|
You may use exactly one of the following interfaces for getting data into and out of your program:
|
||||||
|
* Standard input/standard output
|
||||||
|
* TCP
|
||||||
|
|
||||||
|
You can use whichever is more convenient - we note that some languages make asynchronous
|
||||||
|
IO with standard input/standard output cumbersome and have thus included TCP.
|
||||||
|
|
||||||
|
If you do choose to use TCP, please have your server listen on port `8124`.
|
||||||
|
|
||||||
|
A sample TCP client, `propulsion_tcp_client.py`, is provided that plumbs standard input
|
||||||
|
to TCP writes and likewise plumbs TCP reads to standard output.
|
||||||
|
|
||||||
|
Commands should be delineated by newlines.
|
||||||
|
|
||||||
|
A sample _complete_ execution of your program using standard input and output is shown below
|
||||||
|
|
||||||
|
```
|
||||||
|
./your_program
|
||||||
|
15
|
||||||
|
30
|
||||||
|
firing now!
|
||||||
|
```
|
||||||
|
|
||||||
|
# Submitting your code
|
||||||
|
You may complete this assignment in any programming language that you wish.
|
||||||
|
We're most familiar with Rust and Python at Umbra, but we always enjoy learning
|
||||||
|
new languages and seeing solutions with different tools!
|
||||||
|
|
||||||
|
Your final submission for this exercise should be a zip file including:
|
||||||
|
* The source code of your program.
|
||||||
|
* A brief README with a description of your approach and instructions on how to
|
||||||
|
build and run the program.
|
||||||
|
* Any libraries or frameworks needed to run your program, or instructions for installing them.
|
||||||
|
|
||||||
|
Please ensure that your code is clear and legible before submitting.
|
||||||
|
|
||||||
|
While we don't expect you to write production-quality code for this exercise,
|
||||||
|
readability goes a long way in helping us review your submission.
|
||||||
|
|
BIN
src/.main.rs.swp
Normal file
BIN
src/.main.rs.swp
Normal file
Binary file not shown.
18
src/commands.rs
Normal file
18
src/commands.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
use tokio::time::Duration;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// The commands available to send to the Satellite.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub enum Command
|
||||||
|
{
|
||||||
|
/// Fire the engine in T minus x seconds!
|
||||||
|
Propulsion
|
||||||
|
{
|
||||||
|
/// The amount of seconds to wait before we fire the engines.
|
||||||
|
delay: Duration
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Cancel any waiting commands.
|
||||||
|
Cancel
|
||||||
|
}
|
182
src/main.rs
182
src/main.rs
@ -1,20 +1,186 @@
|
|||||||
//! Rust Challenge
|
//! Rust Challenge
|
||||||
|
|
||||||
|
mod commands;
|
||||||
|
|
||||||
|
|
||||||
mod project;
|
use std::io::Write;
|
||||||
|
|
||||||
|
use tokio::sync::{mpsc, watch};
|
||||||
|
use tokio::time::{Duration, Interval};
|
||||||
|
use tokio::io::AsyncWriteExt;
|
||||||
|
|
||||||
|
use crate::commands::Command;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Print the version of the project.
|
type IoResult<T> = Result<T, std::io::Error>;
|
||||||
fn print_version()
|
|
||||||
|
|
||||||
|
|
||||||
|
/// Reads input from the user until the termination signal is
|
||||||
|
/// received. It will send command messages every time it reads valid input.
|
||||||
|
fn read_user_input(command_sender: mpsc::Sender<Command>,
|
||||||
|
term_sender: watch::Sender<bool>)
|
||||||
|
-> IoResult<()>
|
||||||
{
|
{
|
||||||
println!("{} v{}", project::get_name(), project::get_version());
|
let mut running: bool = true;
|
||||||
|
let mut buffer = String::new();
|
||||||
|
|
||||||
|
// Loop and read the user input.
|
||||||
|
while running
|
||||||
|
{
|
||||||
|
buffer.clear();
|
||||||
|
std::io::stdin().read_line(&mut buffer)?;
|
||||||
|
std::io::stdout().flush().unwrap();
|
||||||
|
|
||||||
|
let input = buffer.trim();
|
||||||
|
|
||||||
|
match input
|
||||||
|
{
|
||||||
|
// A termination method wasn't specified in the document, so
|
||||||
|
// this will terminate when either stop, exit, or quit is entered.
|
||||||
|
"exit" | "stop" | "quit" =>
|
||||||
|
{
|
||||||
|
println!("Exiting application.");
|
||||||
|
running = false;
|
||||||
|
term_sender.send_replace(running);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ =>
|
||||||
/// The usual starting point of your project.
|
|
||||||
fn main()
|
|
||||||
{
|
{
|
||||||
print_version();
|
// Check to see if we were given a number.
|
||||||
|
match input.parse::<i32>()
|
||||||
|
{
|
||||||
|
Ok(seconds) =>
|
||||||
|
{
|
||||||
|
// Here we are just handling the different possible numbers
|
||||||
|
// passed in. -1 cancels commands, less than -1 is ignored
|
||||||
|
// with a message, and greated than -1 is turned into a
|
||||||
|
// propulsion command.
|
||||||
|
if seconds == -1
|
||||||
|
{
|
||||||
|
match command_sender.blocking_send(Command::Cancel)
|
||||||
|
{
|
||||||
|
Ok(_) =>
|
||||||
|
{
|
||||||
|
println!("Cancelling any outstanding commands.")
|
||||||
|
}
|
||||||
|
Err(e) => println!("Failed to send command: {}", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if seconds < -1
|
||||||
|
{
|
||||||
|
println!("All propulsion delay times are given in \
|
||||||
|
seconds within the range of [0, {}]",
|
||||||
|
u32::MAX);
|
||||||
|
println!("A value of -1 will cancel any current \
|
||||||
|
propulsion commands.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
let larger_seconds: u64 = seconds as u64;
|
||||||
|
let delay_duration: Duration = Duration::from_secs(larger_seconds);
|
||||||
|
match command_sender.try_send(Command::Propulsion { delay: delay_duration })
|
||||||
|
{
|
||||||
|
Ok(_) =>
|
||||||
|
{
|
||||||
|
println!("Firing the engines in {} seconds.",
|
||||||
|
seconds)
|
||||||
|
}
|
||||||
|
Err(e) => println!("Failed to send command: {}", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(e) =>
|
||||||
|
{
|
||||||
|
println!("Unable to parse the given input into seconds.");
|
||||||
|
println!("Please specify only seconds until the time to \
|
||||||
|
fire the engines.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn process_commands(mut command_receiver: mpsc::Receiver<Command>,
|
||||||
|
mut term_receiver: watch::Receiver<bool>)
|
||||||
|
->IoResult<()>
|
||||||
|
{
|
||||||
|
let mut stdout = tokio::io::stdout();
|
||||||
|
|
||||||
|
let mut running: bool = true;
|
||||||
|
while running
|
||||||
|
{
|
||||||
|
tokio::select! {
|
||||||
|
Some(command) = command_receiver.recv() =>
|
||||||
|
{
|
||||||
|
match command
|
||||||
|
{
|
||||||
|
Command::Cancel =>
|
||||||
|
{
|
||||||
|
stdout.write_all(b"Received: Cancel\n").await?;
|
||||||
|
stdout.flush().await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Command::Propulsion { delay } =>
|
||||||
|
{
|
||||||
|
let mut buffer: Vec<u8> = Vec::new();
|
||||||
|
writeln!(&mut buffer, "Received: {:?} delay", delay);
|
||||||
|
stdout.write_all(&buffer).await?;
|
||||||
|
stdout.flush().await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = term_receiver.changed() => {
|
||||||
|
stdout.write_all(b"Communication task received shutdown message.").await?;
|
||||||
|
stdout.flush().await?;
|
||||||
|
running = *term_receiver.borrow_and_update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Program entry point.
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> IoResult<()>
|
||||||
|
{
|
||||||
|
// The channel that will be used to send satellite commands between tasks.
|
||||||
|
let (command_sender, mut command_receiver) = mpsc::channel::<Command>(100);
|
||||||
|
|
||||||
|
// The channel that will be used to signal termination of the program.
|
||||||
|
// True means the program is running. False means it has been terminated.
|
||||||
|
//
|
||||||
|
// This could be done as a satellite command since the program is driven by
|
||||||
|
// user interaction and it all happens from the input_task, but this is a
|
||||||
|
// program signal so I prefer to keep it seperate from the command messages.
|
||||||
|
// It also allows for moving termination control to another task, say from
|
||||||
|
// Ctrl+C, if the program was changed to use TCP or something else.
|
||||||
|
let (term_sender, mut term_receiver) = watch::channel(true);
|
||||||
|
|
||||||
|
// Spawn a task to handle reading input from the user. We use a thread here
|
||||||
|
// because tokio recommends it for the blocking read calls for interactive
|
||||||
|
// user input.
|
||||||
|
let input_task = tokio::task::spawn_blocking(move || {
|
||||||
|
read_user_input(command_sender, term_sender)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Spawn a task to handle simulating the satellite.
|
||||||
|
let sim_task = tokio::spawn(async move {
|
||||||
|
process_commands(command_receiver, term_receiver).await
|
||||||
|
});
|
||||||
|
|
||||||
|
let (sim_result, input_result) = tokio::join!(sim_task, input_task);
|
||||||
|
sim_result?;
|
||||||
|
input_result??;
|
||||||
|
println!("Shutdown complete.");
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
//! This is where the Projects build information can be retreived from.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// The environment variable defined by Cargo for the name.
|
|
||||||
const NAME: Option<&str> = option_env!("CARGO_PKG_NAME");
|
|
||||||
|
|
||||||
/// The environment variable defined by Cargo for the version.
|
|
||||||
const VERSION: Option<&str> = option_env!("CARGO_PKG_VERSION");
|
|
||||||
|
|
||||||
/// The string to display if a value is not defined during compile time.
|
|
||||||
const NOT_DEFINED: &'static str = "UNDEFINED";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Returns the name of the program as defined by the CARGO_PKG_NAME. This is
|
|
||||||
/// 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.
|
|
||||||
pub fn get_name() -> &'static str
|
|
||||||
{
|
|
||||||
NAME.unwrap_or(NOT_DEFINED)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Returns the name of the program as defined by the CARGO_PKG_VERSION. This is
|
|
||||||
/// 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.
|
|
||||||
pub fn get_version() -> &'static str
|
|
||||||
{
|
|
||||||
VERSION.unwrap_or(NOT_DEFINED)
|
|
||||||
}
|
|
3
src/satellite.rs
Normal file
3
src/satellite.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pub struct Satellite
|
||||||
|
{
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user