fix: Lock verschwindet nicht mehr - Token-Refresh + laengerer Timeout
Problem: Lock verschwand nach 5 Minuten weil: 1. JWT-Token nach 15 Min ablief -> Heartbeat schlug still fehl 2. Server gab Lock nach 5 Min ohne Heartbeat frei Fix Client: - Token-Refresh alle 10 Minuten (vor dem 15-Min-Ablauf) - Aktualisiert den Token in der shared API-Instanz - Heartbeat nutzt immer den aktuellen Token Fix Backend: - Lock-Timeout von 5 auf 15 Minuten erhoeht - Genug Puffer fuer Netzwerk-Probleme oder kurze Unterbrechungen Timeline: 0s -> Lock + Heartbeat alle 10s 600s -> Token-Refresh 900s -> Lock wuerde erst jetzt ablaufen (15 Min ohne Heartbeat) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b937351556
commit
e9638cc6ed
|
|
@ -2,8 +2,9 @@ from datetime import datetime, timezone, timedelta
|
||||||
|
|
||||||
from app.extensions import db
|
from app.extensions import db
|
||||||
|
|
||||||
# Lock expires after 5 minutes without heartbeat
|
# Lock expires after 15 minutes without heartbeat
|
||||||
LOCK_TIMEOUT_MINUTES = 5
|
# Client sends heartbeat every 10 seconds and refreshes JWT every 10 minutes
|
||||||
|
LOCK_TIMEOUT_MINUTES = 15
|
||||||
|
|
||||||
|
|
||||||
class FileLock(db.Model):
|
class FileLock(db.Model):
|
||||||
|
|
|
||||||
|
|
@ -481,19 +481,35 @@ fn start_background_sync(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Heartbeat every 60s + check if opened files are still in use
|
// Heartbeat + token refresh + check if opened files still in use
|
||||||
let app_hb = app.clone();
|
let app_hb = app.clone();
|
||||||
let api_hb = api.clone();
|
let api_hb = api.clone();
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
let mut api_mut = api_hb.clone();
|
||||||
|
let mut token_refresh_counter = 0u32;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
std::thread::sleep(Duration::from_secs(10));
|
std::thread::sleep(Duration::from_secs(10));
|
||||||
let state = app_hb.state::<AppState>();
|
let state = app_hb.state::<AppState>();
|
||||||
|
|
||||||
|
// Refresh JWT token every 10 minutes (before 15 min expiry)
|
||||||
|
token_refresh_counter += 10;
|
||||||
|
if token_refresh_counter >= 600 {
|
||||||
|
token_refresh_counter = 0;
|
||||||
|
if let Ok(new_token) = rt.block_on(api_mut.refresh_token()) {
|
||||||
|
// Update the shared API instance with new token
|
||||||
|
if let Some(ref mut api) = *state.api.lock().unwrap() {
|
||||||
|
api.access_token = new_token;
|
||||||
|
}
|
||||||
|
eprintln!("[Auth] Token refreshed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Heartbeat for locked files
|
// Heartbeat for locked files
|
||||||
let locked = state.locked_files.lock().unwrap().clone();
|
let locked = state.locked_files.lock().unwrap().clone();
|
||||||
for file_id in &locked {
|
for file_id in &locked {
|
||||||
let _ = rt.block_on(api_hb.heartbeat(*file_id));
|
let _ = rt.block_on(api_mut.heartbeat(*file_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if opened files are still in use by another process
|
// Check if opened files are still in use by another process
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue