Ich habe einen Backend -Server mit Actix_Web in Rust geschrieben. Ich habe auch eine Frontend, die mit React und Next in JavaScript geschrieben ist. Da dies nicht ordnungsgemäß funktioniert (JS .Fetch -Anfragen werden weder in der Registerkarte Netzwerk noch abgeschlossen angezeigt, noch werden die angehängten .- und .catch -Handler ausgelöst), habe ich beschlossen, Aufgaben zu verwenden, die in einem separaten Thread ausgeführt werden, und dann a einstellen a Der globale Staat abhängig vom Ergebnis der Aufgabe. Es scheint Relevanter Code: < /p>
Relevante main.rs Backend -Code < /p>
#[allow(non_snake_case)]
#[derive(Clone)]
/// Current state of the application used to keep track of the logged in users, DoS/Brute force
/// attack requests and sharing a instance of the System struct.
struct AppState {
login_requests: Arc<
Mutex<
HashMap<
String, /* IP Adress of caller */
(
u128, /* Unix Timestamp of last request */
u64, /* Number of requests since last reset */
),
>,
>,
>,
login_token: Arc,
system: Arc,
username: Arc,
net_down: Arc,
net_up: Arc,
net_interface: Arc,
cpu_usage: Arc,
net_connected_interfaces: Arc,
update_jobs: Arc
}
impl AppState {
/// Initiate a new AppState
fn new() -> Self {
let random_string: Vec = (0..128).map(|_| rand::random::()).collect();
AppState {
login_requests: Arc::new(Mutex::new(HashMap::new())),
login_token: Arc::new(Mutex::new(
String::from_utf8_lossy(&random_string).to_string(),
)),
system: Arc::new(Mutex::new(System::new())),
username: Arc::new(Mutex::new(String::new())),
net_up: Arc::new(Mutex::new(0_f64)),
net_down: Arc::new(Mutex::new(0_f64)),
net_interface: Arc::new(Mutex::new(String::new())),
net_connected_interfaces: Arc::new(Mutex::new(0_i32)),
cpu_usage: Arc::new(Mutex::new(0_f32)),
update_jobs: Arc::new(RwLock::new(HashMap::new()))
}
}
...
// Left out as it would make this code block very long
}
#[derive(Debug)]
#[derive(Clone)]
enum BackgroundTaskState {
Success,
Fail,
SuccessOutput(String),
FailOutput(String),
Pending
}
// Route that is used to check if a task aka. job has already finished
#[get("/api/fetchJobStatus/{jobId}")]
async fn fetch_job_status(
session: Session,
state: Data,
path: web::Path
) -> HttpResponse {
if !is_admin_state(&session, state.clone()) {
return HttpResponse::Forbidden().body("This resource is blocked.");
}
let requested_id = path.into_inner().to_string();
let jobs = state.update_jobs.read().unwrap().clone();
let background_state = jobs.get(&uuid::Uuid::parse_str(&requested_id).unwrap());
dbg!(&jobs);
fn clear_task(state: Data, task: String) {
let mut jobs = state.update_jobs.write().unwrap().clone();
jobs.remove(&uuid::Uuid::from_str(&task).unwrap());
*state.update_jobs.write().unwrap() = jobs;
()
}
match background_state {
Some(bs) => {
match bs {
BackgroundTaskState::Success => {
clear_task(state, requested_id);
HttpResponse::Ok().finish()
},
BackgroundTaskState::Fail => {
clear_task(state, requested_id);
HttpResponse::UnprocessableEntity().finish()},
BackgroundTaskState::SuccessOutput(s) =>{
clear_task(state, requested_id);
HttpResponse::Ok().body(s.clone())},
BackgroundTaskState::FailOutput(f) => {
clear_task(state, requested_id);
HttpResponse::UnprocessableEntity().body(f.clone())},
BackgroundTaskState::Pending => HttpResponse::Accepted().finish()
}
},
None => HttpResponse::InternalServerError().body("Failed to fetch background task state")
}
}
// Examplary route that starts a task/job
#[post("/api/installPackage")]
/// Install a package on the users system.
///
/// It requires the package name along side the sudo password in the request body.
/// This only works under apt, dnf and pacman.
async fn install_package(
session: Session,
json: web::Json
,
state: Data,
) -> HttpResponse {
if !is_admin_state(&session, state.clone()) {
return HttpResponse::Forbidden().body("This resource is blocked.");
}
let job_id = Uuid::new_v4();
tokio::spawn(async move {
match packages::install_package(json.packageName.to_string(), json.sudoPassword.to_string()) {
Ok(_) => state.update_jobs.write().unwrap().insert(job_id, BackgroundTaskState::Success),
Err(_) => state.update_jobs.write().unwrap().insert(job_id, BackgroundTaskState::Fail),
}});
HttpResponse::Ok().body(job_id.to_string())
}
< /code>
Relevante Frontend -Pakete.jsx Code < /p>
function startTask(adress, options = {}, interval = 3000) {
return new Promise((resolve, reject) => {
fetch(adress, options).then((res) => {
if (res.ok) {
res.text().then((uuid) => {
let ready_for_fetch = true;
let ivd = setInterval(() => {
if (!ready_for_fetch) return;
ready_for_fetch = false
fetch(fetchURLPrefix + "/api/fetchJobStatus/" + uuid).then(
(checkRes) => {
ready_for_fetch = true;
if (checkRes.status === 200) {
clearInterval(ivd);
resolve(checkRes);
} else if (checkRes.status === 422 || checkRes.status === 500) {
clearInterval(ivd);
reject(checkRes);
}}
);
}, interval);
});
}
});
});
}
< /code>
Ich habe die Netzwerkaktivität überwacht, die erwarteten Ergebnisse mit der Befehlszeile überprüft, ... und nichts scheint das Problem zu verursachen. Die Netzwerkanfragen scheinen zu scheitern, egal was passiert.
Backend und Frontend scheinen Daten nicht mit langsamen Verbindungen auszutauschen ⇐ JavaScript
-
- Similar Topics
- Replies
- Views
- Last post