Compare commits
10 Commits
Author | SHA1 | Date |
---|---|---|
Ian Wijma | e3623f4ecc | |
Ian Wijma | 806d17328c | |
Ian Wijma | ef1e2c56c0 | |
Ian Wijma | 5c19c27136 | |
Ian Wijma | aad5010257 | |
Ian Wijma | ffa6d18e5e | |
Ian Wijma | 049a75e300 | |
Ian Wijma | dcf83a351f | |
Ian Wijma | 66ab232c9d | |
Ian Wijma | 99947dbefd |
|
@ -1,9 +1,12 @@
|
||||||
name: Releasing
|
name: Releasing
|
||||||
run-name: ${{ gitea.actor }} is building a release releasing 🚀
|
run-name: ${{ github.actor }} is building the files for a release 🚀
|
||||||
on: [release]
|
on:
|
||||||
|
release:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
|
name: release ${{ matrix.target }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
@ -18,19 +21,9 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@master
|
||||||
- name: Compile and release
|
- name: Compile and release
|
||||||
id: compile
|
|
||||||
uses: rust-build/rust-build.action@v1.4.4
|
uses: rust-build/rust-build.action@v1.4.4
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
RUSTTARGET: ${{ matrix.target }}
|
RUSTTARGET: ${{ matrix.target }}
|
||||||
ARCHIVE_TYPES: ${{ matrix.archive }}
|
ARCHIVE_TYPES: ${{ matrix.archive }}
|
||||||
UPLOAD_MODE: 'none'
|
|
||||||
- name: Upload artifact
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: Binary
|
|
||||||
path: |
|
|
||||||
${{ steps.compile.outputs.BUILT_ARCHIVE }}
|
|
||||||
${{ steps.compile.outputs.BUILT_CHECKSUM }}
|
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kr"
|
name = "kr"
|
||||||
version = "1.0.0"
|
version = "1.0.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "kr"
|
name = "kr"
|
||||||
version = "1.0.1"
|
version = "1.0.3"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
@ -13,4 +13,3 @@ strip = true # Automatically strip symbols from the binary.
|
||||||
opt-level = "z" # Optimize for size.
|
opt-level = "z" # Optimize for size.
|
||||||
lto = true
|
lto = true
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 119 KiB |
|
@ -0,0 +1,35 @@
|
||||||
|
Keep Running
|
||||||
|
---
|
||||||
|
|
||||||
|
Keep running is a quick and easy way to **keep** a process **running** during development or other **non-production** tasks.
|
||||||
|
|
||||||
|
> Please for the love of sanity, do not use this is production...
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
Below you will see the output of the `--help` command.
|
||||||
|
Do note that if you don't specify any `--per-*` flag, it defaults to `--per-minute=4`.
|
||||||
|
|
||||||
|
```
|
||||||
|
Usage: kr [OPTIONS] <COMMAND>
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
<COMMAND>
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--per-minute <PER_MINUTE> [default: 0]
|
||||||
|
--per-hour <PER_HOUR> [default: 0]
|
||||||
|
--delay <DELAY> [default: 0]
|
||||||
|
-h, --help Print help
|
||||||
|
-V, --version Print version
|
||||||
|
```
|
||||||
|
|
||||||
|
# Use cases
|
||||||
|
|
||||||
|
## Game servers
|
||||||
|
|
||||||
|
/keep-running/ is a great tool to run, for example, a Modded minecraft server.
|
||||||
|
As it automatically restarts the server if a crash occurs.
|
||||||
|
|
||||||
|
![img.png](assets/vault-hunters-3rd.png)
|
||||||
|
|
74
src/main.rs
74
src/main.rs
|
@ -17,7 +17,7 @@ struct Arguments {
|
||||||
delay: u8,
|
delay: u8,
|
||||||
|
|
||||||
#[arg()]
|
#[arg()]
|
||||||
command: String
|
command: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
const SECONDS_IN_A_MINUTE: u16 = 60;
|
const SECONDS_IN_A_MINUTE: u16 = 60;
|
||||||
|
@ -29,30 +29,36 @@ struct Retry {
|
||||||
max_retries: u8,
|
max_retries: u8,
|
||||||
timespan: u16,
|
timespan: u16,
|
||||||
restart_delay: u8,
|
restart_delay: u8,
|
||||||
restart_name: String
|
restart_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let arguments = Arguments::parse();
|
let arguments = Arguments::parse();
|
||||||
|
|
||||||
let mut retry: Retry = Retry {
|
let mut max_retries = 4;
|
||||||
command: arguments.command,
|
let mut timespan = SECONDS_IN_A_MINUTE;
|
||||||
history: Vec::new(),
|
let mut restart_name = String::from("minute");
|
||||||
max_retries: 4,
|
|
||||||
timespan: SECONDS_IN_A_MINUTE,
|
|
||||||
restart_delay: arguments.delay,
|
|
||||||
restart_name: "minute".to_string(),
|
|
||||||
};
|
|
||||||
|
|
||||||
if arguments.per_minute > 0 {
|
let Arguments { per_minute, per_hour, .. } = arguments;
|
||||||
retry.max_retries = arguments.per_minute;
|
if per_minute > 0 {
|
||||||
} else if arguments.per_hour > 0 {
|
max_retries = per_minute;
|
||||||
retry.max_retries = arguments.per_hour;
|
} else if per_hour > 0 {
|
||||||
retry.timespan = SECONDS_IN_A_HOUR;
|
max_retries = per_hour;
|
||||||
retry.restart_name = "hour".to_string();
|
timespan = SECONDS_IN_A_HOUR;
|
||||||
|
restart_name = String::from("hour");
|
||||||
}
|
}
|
||||||
|
|
||||||
run_command(&mut retry)
|
let Arguments { command, delay: restart_delay, .. } = arguments;
|
||||||
|
let retry: Retry = Retry {
|
||||||
|
max_retries,
|
||||||
|
timespan,
|
||||||
|
restart_name,
|
||||||
|
command,
|
||||||
|
restart_delay,
|
||||||
|
history: Vec::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
run_command(retry)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_now() -> u64 {
|
fn get_now() -> u64 {
|
||||||
|
@ -62,26 +68,29 @@ fn get_now() -> u64 {
|
||||||
.as_secs();
|
.as_secs();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_history(retry: &mut Retry) {
|
fn push_history(mut history: Vec<u64>, timespan: u16) -> Vec<u64> {
|
||||||
retry.history.push(get_now() + u64::from(retry.timespan));
|
history.push(get_now() + u64::from(timespan));
|
||||||
|
|
||||||
|
return history.to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_history(retry: &mut Retry) {
|
fn update_history(mut history: Vec<u64>) -> Vec<u64> {
|
||||||
let now = get_now();
|
let now = get_now();
|
||||||
let clear_times: Vec<u64> = retry
|
let clear_times: Vec<u64> = history
|
||||||
.history
|
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|&time| time <= &now)
|
.filter(|&time| time <= &now)
|
||||||
.map(|&time| time)
|
.map(|&time| time)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for time in clear_times {
|
for time in clear_times {
|
||||||
retry.history.retain(|&h| h != time);
|
history.retain(|&h| h != time);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_history(retry: &Retry) -> bool {
|
return history.to_owned();
|
||||||
return retry.history.len().lt(&usize::from(retry.max_retries))
|
}
|
||||||
|
|
||||||
|
fn check_history(history: &Vec<u64>, max_retries: u8) -> bool {
|
||||||
|
return history.len().lt(&usize::from(max_retries))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_process(retry: &Retry) -> Result<Child, std::io::Error> {
|
fn spawn_process(retry: &Retry) -> Result<Child, std::io::Error> {
|
||||||
|
@ -101,8 +110,8 @@ fn spawn_process(retry: &Retry) -> Result<Child, std::io::Error> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_command(retry: &mut Retry) {
|
fn run_command(mut retry: Retry) {
|
||||||
let mut process = spawn_process(retry)
|
let mut process = spawn_process(&retry)
|
||||||
.expect("Process failed on startup");
|
.expect("Process failed on startup");
|
||||||
|
|
||||||
let exit_code = match process.wait() {
|
let exit_code = match process.wait() {
|
||||||
|
@ -117,9 +126,10 @@ fn run_command(retry: &mut Retry) {
|
||||||
println!("Exit code: {}", exit_code);
|
println!("Exit code: {}", exit_code);
|
||||||
} else {
|
} else {
|
||||||
println!("[CRASH] exit code: {}", exit_code);
|
println!("[CRASH] exit code: {}", exit_code);
|
||||||
push_history(retry);
|
let pushed_history = push_history(retry.history, retry.timespan);
|
||||||
update_history(retry);
|
let updated_history = update_history(pushed_history);
|
||||||
if check_history(retry) {
|
if check_history(&updated_history, retry.max_retries) {
|
||||||
|
retry.history = updated_history;
|
||||||
println!("Restarting...");
|
println!("Restarting...");
|
||||||
restart(retry);
|
restart(retry);
|
||||||
} else {
|
} else {
|
||||||
|
@ -128,7 +138,7 @@ fn run_command(retry: &mut Retry) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn restart(retry: &mut Retry) {
|
fn restart(retry: Retry) {
|
||||||
sleep(Duration::from_secs(u64::from(retry.restart_delay)));
|
sleep(Duration::from_secs(u64::from(retry.restart_delay)));
|
||||||
|
|
||||||
run_command(retry);
|
run_command(retry);
|
||||||
|
|
Loading…
Reference in New Issue