Update dependencies and enhance WebSocket server logging: Add 'chrono' and 'android_system_properties' to Cargo.lock, improve error handling and logging in websocket_server.rs, and streamline character creation notifications in worker modules for better clarity and maintainability.

This commit is contained in:
Torsten Schulz (local)
2026-01-28 14:21:28 +01:00
parent 2ac474fe0c
commit c9e0781b61
14 changed files with 1174 additions and 1814 deletions

View File

@@ -1,10 +1,9 @@
use crate::db::{ConnectionPool, DbError};
use crate::message_broker::MessageBroker;
use std::cmp::min;
use std::collections::HashSet;
use std::sync::atomic::Ordering;
use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
use std::sync::Arc;
use std::time::Duration;
use super::base::{BaseWorker, Worker, WorkerState};
use crate::worker::sql::{
@@ -15,11 +14,7 @@ use crate::worker::sql::{
QUERY_DELETE_TRANSPORT,
QUERY_GET_BRANCH_REGION,
QUERY_UPDATE_TRANSPORT_SIZE,
QUERY_GET_BROKEN_VEHICLES,
QUERY_DELETE_TRANSPORTS_BY_VEHICLE,
QUERY_DELETE_VEHICLE,
};
use crate::worker::{insert_notification_conn, publish_update_status};
#[derive(Debug, Clone)]
struct ArrivedTransport {
id: i32,
@@ -51,26 +46,13 @@ impl TransportWorker {
}
fn run_loop(pool: ConnectionPool, broker: MessageBroker, state: Arc<WorkerState>) {
let mut last_vehicle_check: Option<Instant> = None;
while state.running_worker.load(Ordering::Relaxed) {
if let Err(err) = Self::process_arrived_transports(&pool, &broker) {
eprintln!("[TransportWorker] Fehler in process_arrived_transports: {err}");
}
// Stündlich Fahrzeuge prüfen (condition==0 => löschen + Notification)
let now = Instant::now();
let should_vehicle_check = last_vehicle_check
.map(|t| now.saturating_duration_since(t) >= Duration::from_secs(3600))
.unwrap_or(true);
if should_vehicle_check {
if let Err(err) = Self::cleanup_broken_vehicles(&pool, &broker) {
eprintln!("[TransportWorker] Fehler in cleanup_broken_vehicles: {err}");
}
last_vehicle_check = Some(now);
}
// Minütlich prüfen (nicht sekündlich pollen)
for _ in 0..60 {
// Einmal pro Sekunde prüfen
for _ in 0..1 {
if !state.running_worker.load(Ordering::Relaxed) {
break;
}
@@ -79,104 +61,17 @@ impl TransportWorker {
}
}
fn cleanup_broken_vehicles(
pool: &ConnectionPool,
broker: &MessageBroker,
) -> Result<(), DbError> {
let mut conn = pool
.get()
.map_err(|e| DbError::new(format!("DB-Verbindung fehlgeschlagen: {e}")))?;
conn.prepare("get_broken_vehicles", QUERY_GET_BROKEN_VEHICLES)?;
conn.prepare(
"delete_transports_by_vehicle",
QUERY_DELETE_TRANSPORTS_BY_VEHICLE,
)?;
conn.prepare("delete_vehicle", QUERY_DELETE_VEHICLE)?;
let rows = conn.execute("get_broken_vehicles", &[])?;
if rows.is_empty() {
return Ok(());
}
let mut affected_users: HashSet<i32> = HashSet::new();
let mut deleted_count = 0usize;
for row in rows {
let vehicle_id = parse_i32(&row, "vehicle_id", -1);
let user_id = parse_i32(&row, "user_id", -1);
if vehicle_id < 0 || user_id < 0 {
continue;
}
// 1) Laufende/alte Transporte des Fahrzeugs entfernen (falls vorhanden),
// damit das Löschen des Fahrzeugs nicht an FK-Constraints scheitert.
if let Err(err) = conn.execute("delete_transports_by_vehicle", &[&vehicle_id]) {
eprintln!(
"[TransportWorker] Fehler beim Löschen von Transporten für vehicle_id={}: {}",
vehicle_id, err
);
// weiter versuchen: evtl. existieren keine oder keine Constraints
}
// 2) Fahrzeug löschen
if let Err(err) = conn.execute("delete_vehicle", &[&vehicle_id]) {
eprintln!(
"[TransportWorker] Fehler beim Löschen von vehicle_id={}: {}",
vehicle_id, err
);
continue;
}
// 3) Notification an Besitzer (DB)
let tr = format!(
r#"{{"tr":"vehicle_destroyed","vehicle_id":{}}}"#,
vehicle_id
);
if let Err(err) = insert_notification_conn(&mut conn, user_id, &tr, None) {
eprintln!(
"[TransportWorker] Fehler beim Schreiben der Vehicle-Notification (user_id={}, vehicle_id={}): {}",
user_id, vehicle_id, err
);
}
affected_users.insert(user_id);
deleted_count += 1;
}
if deleted_count > 0 {
eprintln!(
"[TransportWorker] {} Fahrzeug(e) mit condition=0 gelöscht",
deleted_count
);
}
// 4) Frontend informieren: Branches/Status neu laden
for user_id in affected_users {
publish_update_status(broker, user_id);
}
Ok(())
}
fn process_arrived_transports(
pool: &ConnectionPool,
broker: &MessageBroker,
) -> Result<(), DbError> {
let transports = Self::load_arrived_transports(pool)?;
if !transports.is_empty() {
eprintln!(
"[TransportWorker] {} angekommene Transport(e) gefunden",
transports.len()
);
}
for t in transports {
if let Err(err) = Self::handle_arrived_transport(pool, broker, &t) {
eprintln!(
"[TransportWorker] Fehler beim Verarbeiten von Transport {} (vehicle_id={}, product_id={:?}, size={}): {}",
t.id, t.vehicle_id, t.product_id, t.size, err
"[TransportWorker] Fehler beim Verarbeiten von Transport {}: {err}",
t.id
);
}
}
@@ -192,19 +87,6 @@ impl TransportWorker {
conn.prepare("get_arrived_transports", QUERY_GET_ARRIVED_TRANSPORTS)?;
let rows = conn.execute("get_arrived_transports", &[])?;
if rows.is_empty() {
// Nur alle 60 Sekunden loggen, um Log-Flut zu vermeiden
static LAST_LOG: Mutex<Option<Instant>> = Mutex::new(None);
let mut last_log = LAST_LOG.lock().unwrap();
let should_log = last_log
.map(|t| t.elapsed().as_secs() >= 60)
.unwrap_or(true);
if should_log {
eprintln!("[TransportWorker] Keine angekommenen Transporte gefunden");
*last_log = Some(Instant::now());
}
}
let mut result = Vec::with_capacity(rows.len());
for row in rows {
let id = parse_i32(&row, "id", -1);
@@ -341,13 +223,6 @@ impl TransportWorker {
);
broker.publish(target_inventory_message);
}
} else {
// Nichts konnte eingelagert werden - Transport bleibt unverändert
// Logge dies, damit wir sehen, dass der Transport wartet
eprintln!(
"[TransportWorker] Transport {} wartet: Kein Lagerplatz verfügbar (branch_id={}, product_id={}, size={})",
t.id, t.target_branch_id, product_id, t.size
);
}
// Keine Notification für wartende Transporte, um Notification-System zu entlasten.