feat: add per-account lock file protection via fs2
Prevent running multiple tele-tui instances with the same account by using advisory file locks (flock). Lock is acquired before raw mode so errors print to normal terminal. Account switching acquires new lock before releasing old. Also log set_tdlib_parameters errors via tracing instead of silently discarding them. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
32
src/main.rs
32
src/main.rs
@@ -81,6 +81,15 @@ async fn main() -> Result<(), io::Error> {
|
||||
)
|
||||
.unwrap_or(db_path);
|
||||
|
||||
// Acquire per-account lock BEFORE raw mode (so error prints to normal terminal)
|
||||
let account_lock = accounts::acquire_lock(
|
||||
account_arg.as_deref().unwrap_or(&accounts_config.default_account),
|
||||
)
|
||||
.unwrap_or_else(|e| {
|
||||
eprintln!("Error: {}", e);
|
||||
std::process::exit(1);
|
||||
});
|
||||
|
||||
// Отключаем логи TDLib ДО создания клиента
|
||||
disable_tdlib_logs();
|
||||
|
||||
@@ -102,6 +111,7 @@ async fn main() -> Result<(), io::Error> {
|
||||
// Create app state with account-specific db_path
|
||||
let mut app = App::new(config, db_path);
|
||||
app.current_account_name = account_name;
|
||||
app.account_lock = Some(account_lock);
|
||||
|
||||
// Запускаем инициализацию TDLib в фоне (только для реального клиента)
|
||||
let client_id = app.td_client.client_id();
|
||||
@@ -110,7 +120,7 @@ async fn main() -> Result<(), io::Error> {
|
||||
let db_path_str = app.td_client.db_path.to_string_lossy().to_string();
|
||||
|
||||
tokio::spawn(async move {
|
||||
let _ = tdlib_rs::functions::set_tdlib_parameters(
|
||||
if let Err(e) = tdlib_rs::functions::set_tdlib_parameters(
|
||||
false, // use_test_dc
|
||||
db_path_str, // database_directory
|
||||
"".to_string(), // files_directory
|
||||
@@ -127,7 +137,10 @@ async fn main() -> Result<(), io::Error> {
|
||||
env!("CARGO_PKG_VERSION").to_string(), // application_version
|
||||
client_id,
|
||||
)
|
||||
.await;
|
||||
.await
|
||||
{
|
||||
tracing::error!("set_tdlib_parameters failed: {:?}", e);
|
||||
}
|
||||
});
|
||||
|
||||
let res = run_app(&mut terminal, &mut app).await;
|
||||
@@ -406,6 +419,21 @@ async fn run_app<B: ratatui::backend::Backend, T: tdlib::TdClientTrait>(
|
||||
|
||||
// Check pending account switch
|
||||
if let Some((account_name, new_db_path)) = app.pending_account_switch.take() {
|
||||
// 0. Acquire lock for new account before switching
|
||||
match accounts::acquire_lock(&account_name) {
|
||||
Ok(new_lock) => {
|
||||
// Release old lock
|
||||
if let Some(old_lock) = app.account_lock.take() {
|
||||
accounts::release_lock(old_lock);
|
||||
}
|
||||
app.account_lock = Some(new_lock);
|
||||
}
|
||||
Err(e) => {
|
||||
app.error_message = Some(e);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Stop playback
|
||||
app.stop_playback();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user