Skip to content

Commit a00a397

Browse files
committed
migrate all deps to modern versions
1 parent 626d85b commit a00a397

File tree

9 files changed

+271
-206
lines changed

9 files changed

+271
-206
lines changed

Cargo.toml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,23 @@ edition = "2021"
88
[dependencies]
99
ansi_escapers = "0.2.0"
1010
async-std = { version = "1.12.0", features = ["tokio03", "tokio02", "tokio1"] }
11-
axum = { version = "0.6.20", features = ["tracing", "ws", "macros", "headers"] }
12-
axum-extra = "0.7.7"
11+
axum = { version = "0.8.4", features = ["tracing", "ws", "macros"] }
12+
axum-extra = "0.10.1"
1313
colorlab = {git = "https://github.com/SturdyFool10/ColorLab.git"}
14-
crossterm = "0.27.0"
14+
crossterm = "0.29.0"
1515
futures = "0.3.28"
1616
futures-util = "0.3.28"
1717
regex = "1.10.2"
1818
serde = { version = "1.0.183", features = ["derive", "serde_derive"] }
1919
serde_json = { version = "1.0.105", features = ["float_roundtrip"] }
2020
tokio = { version = "1.31.0", features = ["full", "tracing"] }
21-
tokio-tungstenite = "0.20.0"
22-
tower = { version = "0.4.13", features = ["full", "tokio"] }
23-
tower-http = { version = "0.4.3", features = ["full", "trace"] }
21+
tokio-tungstenite = "0.27.0"
22+
tower = { version = "0.5.2", features = ["full", "tokio"] }
23+
tower-http = { version = "0.6.6", features = ["full", "trace"] }
2424
tracing = "0.1.37"
2525
tracing-subscriber = "0.3.17"
26-
dashmap = "5.5.3"
26+
dashmap = "6.1.0"
27+
hyper = "1.7.0"
2728

2829
[target.'cfg(target_os = "windows")'.build-dependencies]
2930
winres = "0.1"

src/controlled_program.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,20 @@ impl Drop for ControlledProgramInstance {
136136

137137
impl ControlledProgramInstance {
138138
pub fn new(name: &str, exe_path: &str, arguments: Vec<String>, working_dir: String) -> Self {
139+
use std::fs;
140+
use std::path::Path;
141+
142+
// Ensure the working directory exists, create if it doesn't
143+
let working_dir_path = Path::new(&working_dir);
144+
if !working_dir_path.exists() {
145+
if let Err(e) = fs::create_dir_all(&working_dir_path) {
146+
panic!(
147+
"Failed to create working directory {:?}: {}",
148+
working_dir_path, e
149+
);
150+
}
151+
}
152+
139153
let mut process = Command::new(exe_path);
140154
let mut process = process //this line needs to be here to prevent dropped value error
141155
.stdin(Stdio::piped()) //pipe stdin

src/html_src/index.js

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
window.lastLogLineCount = window.lastLogLineCount || {};
2+
13
function closeMenu() {
24
$("#menu").animate(
35
{
@@ -502,17 +504,18 @@ $(document).ready(function () {
502504
var server = obj.servers[index];
503505
let serverName = server.name;
504506
addDropdownNoDupe(serverName, !server.active);
505-
if (justStarted) {
506-
// Do not update config here, wait for ConfigInfo
507-
var lines = server.output.split("\r\n");
508-
for (linePos in lines) {
509-
var line = lines[linePos];
510-
var p = $('<p class="STDOutMessage"></p>').appendTo(
511-
"." + serverName + "Out",
512-
)[0];
507+
var outDiv = $("." + serverName + "Out");
508+
var lines = server.output.split("\r\n");
509+
var lastCount = window.lastLogLineCount[serverName] || 0;
510+
// Only append new lines
511+
for (let i = lastCount; i < lines.length; i++) {
512+
var line = lines[i];
513+
if (line.trim() !== "") {
514+
var p = $('<p class="STDOutMessage"></p>').appendTo(outDiv)[0];
513515
p.innerHTML = line;
514516
}
515517
}
518+
window.lastLogLineCount[serverName] = lines.length;
516519
}
517520
window.serverInfoObj = obj;
518521
break;
@@ -521,6 +524,10 @@ $(document).ready(function () {
521524
// Split on <br> (or <br/>), so each log line is its own <p>
522525
var lines = str.split(/<br\s*\/?>/i);
523526
var outDiv = $("." + obj.server_name + "Out")[0];
527+
if (!outDiv) {
528+
console.warn("Output div not found for server:", obj.server_name);
529+
break;
530+
}
524531
var shouldScroll = outDiv.scrollTop == outDiv.scrollHeight;
525532
lines.forEach(function (line) {
526533
if (line.trim() !== "") {

src/main.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,53 @@ async fn main() -> Result<(), String> {
5656
{
5757
info!("Starting {} tasks", handles.len());
5858
}
59+
// Spawn shutdown handler to kill all child processes on exit
60+
let app_state_clone = app_state.clone();
61+
let shutdown = async move |reason: &str| {
62+
info!(
63+
"Shutdown signal received ({}), terminating all child processes...",
64+
reason
65+
);
66+
let mut servers = app_state_clone.servers.lock().await;
67+
for server in servers.iter_mut() {
68+
let _ = server.stop().await;
69+
}
70+
info!("All child processes terminated.");
71+
std::process::exit(0);
72+
};
73+
74+
// Ctrl+C handler
75+
let app_state_clone_ctrlc = app_state.clone();
76+
tokio::spawn({
77+
let shutdown = shutdown.clone();
78+
async move {
79+
use tokio::signal;
80+
signal::ctrl_c().await.expect("Failed to listen for ctrl_c");
81+
shutdown("ctrl_c").await;
82+
}
83+
});
84+
85+
// T key handler
86+
let app_state_clone_t = app_state.clone();
87+
tokio::spawn({
88+
let shutdown = shutdown.clone();
89+
async move {
90+
use crossterm::event::{poll, read, Event, KeyCode};
91+
use tokio::task::yield_now;
92+
loop {
93+
yield_now().await;
94+
if poll(std::time::Duration::from_millis(25)).expect("Failed to poll for events") {
95+
if let Event::Key(key_event) = read().expect("Failed to read event") {
96+
if key_event.code == KeyCode::Char('t') {
97+
shutdown("T key").await;
98+
}
99+
}
100+
}
101+
}
102+
}
103+
});
104+
59105
let _ = tokio::spawn(async_listener!("t", app_state)).await;
60-
info!("Termination key pressed, closing the app.");
61106
exit(0);
62107
}
63108

src/master.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ impl SlaveConnection {
4848
};
4949
let messag = serde_json::to_string(&request_message).unwrap();
5050
// Send requestInfo message
51-
let message = Message::Text(messag);
51+
let message = tokio_tungstenite::tungstenite::Message::Text(messag.into());
5252
let _res = stream.send(message).await;
5353

5454
// Read response
@@ -120,7 +120,7 @@ impl SlaveConnection {
120120
}
121121
}
122122
"ServerOutput" => {
123-
let _ = app_state.tx.send(text.clone());
123+
let _ = app_state.tx.send(text.to_string());
124124
}
125125
_ => {}
126126
}
@@ -152,7 +152,7 @@ impl SlaveConnection {
152152
let message = serde_json::to_string(&stdin_message).unwrap();
153153
// Send stdin message
154154
if let Some(stream) = &mut self.stream {
155-
let message = Message::Text(message);
155+
let message = tokio_tungstenite::tungstenite::Message::Text(message.into());
156156

157157
let _ = tokio::time::timeout(Duration::from_secs_f64(1. / 1000.), stream.send(message))
158158
.await;

src/servers.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ use crate::{
33
};
44
use tracing::*;
55

6+
// Helper to format exit code message for web console
7+
pub fn format_exit_message(exit_code: impl std::fmt::Display) -> String {
8+
format!(
9+
"<span style=\"color: var(--warning, #FFA500);\">[Server exited with code {}]</span>",
10+
exit_code
11+
)
12+
}
13+
614
// Helper function to send server termination message to web console
715
pub async fn send_termination_message(
816
state: &AppState,
@@ -12,10 +20,7 @@ pub async fn send_termination_message(
1220
) {
1321
let termination_msg = ConsoleOutput {
1422
r#type: "ServerOutput".to_owned(),
15-
output: format!(
16-
"<span style=\"color: yellow;\">Program has stopped execution: StopCode: {}</span>",
17-
exit_code
18-
),
23+
output: format_exit_message(exit_code),
1924
server_name,
2025
server_type,
2126
};

src/slave.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ pub async fn start_slave(_state: AppState) {
1717
info!("Starting server on {}", address.replace("0.0.0.0", "*"));
1818

1919
let stateful_router = router.with_state(_state);
20-
axum::Server::bind(&address.parse().unwrap())
21-
.serve(stateful_router.into_make_service())
20+
use axum::serve;
21+
use tokio::net::TcpListener;
22+
23+
let listener = TcpListener::bind(&address).await.unwrap();
24+
serve(listener, stateful_router.into_make_service())
2225
.await
2326
.unwrap();
2427
}

src/webserver.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ use axum::{
33
body::Body,
44
extract::State,
55
http::StatusCode,
6-
response::{IntoResponse, Response},
6+
response::{Html, IntoResponse, Response},
77
routing::get,
88
Router,
99
};
10-
use axum_extra::response::*;
10+
use axum_extra::response::JavaScript;
11+
1112
use tower_http::services::ServeDir;
1213
use tracing::*;
1314

@@ -38,22 +39,25 @@ async fn handle_icon(State(_state): State<AppState>) -> impl IntoResponse {
3839
}
3940
#[no_mangle]
4041
pub async fn start_web_server(_state: AppState) {
41-
let router = get_router(_state.clone()).await; //.route("/ws", get(handle_socket))
42+
use axum::serve;
43+
use tokio::net::TcpListener;
44+
45+
let router = get_router(_state.clone()).await;
4246
let config = _state.config.lock().await;
4347
let mut address = config.interface.clone();
4448
address += (":".to_owned() + config.port.clone().as_str()).as_str();
4549
drop(config);
4650
info!("Starting server on {}", address.replace("0.0.0.0", "*"));
4751

4852
let stateful_router = router.with_state(_state);
49-
axum::Server::bind(&address.parse().unwrap())
50-
.serve(stateful_router.into_make_service())
53+
let listener = TcpListener::bind(&address).await.unwrap();
54+
serve(listener, stateful_router.into_make_service())
5155
.await
5256
.unwrap();
5357
}
5458
#[no_mangle]
5559
async fn main_serve(State(_state): State<AppState>) -> Html<String> {
56-
Html::from(
60+
Html(
5761
include_str!("html_src/index.html")
5862
.to_owned()
5963
.replace("styles!();", include_str!("html_src/style.css")),

0 commit comments

Comments
 (0)