refactor(profile-switch): async post-switch tasks, early lock release, and spawn_blocking for IO
This commit is contained in:
@@ -135,23 +135,7 @@ pub(super) async fn run_switch_job(
|
||||
Ok(Ok(machine_result)) => match machine_result {
|
||||
Ok(cmd_result) => match cmd_result {
|
||||
Ok(success) => {
|
||||
handle::Handle::notify_profile_switch_finished(
|
||||
profile_id.clone(),
|
||||
success,
|
||||
notify,
|
||||
task_id,
|
||||
);
|
||||
close_connections_after_switch(&profile_id).await;
|
||||
if notify && success {
|
||||
handle::Handle::notice_message("info", "Profile Switched");
|
||||
}
|
||||
logging!(
|
||||
info,
|
||||
Type::Cmd,
|
||||
"Profile switch task finished: {} (success={})",
|
||||
profile_id,
|
||||
success
|
||||
);
|
||||
schedule_post_switch_success(profile_id.clone(), success, notify, task_id);
|
||||
Ok(success)
|
||||
}
|
||||
Err(err) => {
|
||||
@@ -340,16 +324,24 @@ pub(super) async fn restore_previous_profile(previous: Option<SmartString>) -> C
|
||||
}
|
||||
|
||||
AsyncHandler::spawn(|| async move {
|
||||
match time::timeout(SAVE_PROFILES_TIMEOUT, profiles_save_file_safe()).await {
|
||||
Ok(Ok(())) => {}
|
||||
Ok(Err(e)) => {
|
||||
logging!(
|
||||
warn,
|
||||
Type::Cmd,
|
||||
"Failed to persist restored configuration asynchronously: {}",
|
||||
e
|
||||
);
|
||||
}
|
||||
let save_future = AsyncHandler::spawn_blocking(|| {
|
||||
futures::executor::block_on(async { profiles_save_file_safe().await })
|
||||
});
|
||||
match time::timeout(SAVE_PROFILES_TIMEOUT, save_future).await {
|
||||
Ok(join_res) => match join_res {
|
||||
Ok(Ok(())) => {}
|
||||
Ok(Err(err)) => {
|
||||
logging!(
|
||||
warn,
|
||||
Type::Cmd,
|
||||
"Failed to persist restored configuration asynchronously: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
Err(join_err) => {
|
||||
logging!(warn, Type::Cmd, "Blocking save task failed: {}", join_err);
|
||||
}
|
||||
},
|
||||
Err(_) => {
|
||||
logging!(
|
||||
warn,
|
||||
@@ -393,6 +385,32 @@ async fn close_connections_after_switch(profile_id: &SmartString) {
|
||||
}
|
||||
}
|
||||
|
||||
fn schedule_close_connections(profile_id: SmartString) {
|
||||
AsyncHandler::spawn(|| async move {
|
||||
close_connections_after_switch(&profile_id).await;
|
||||
});
|
||||
}
|
||||
|
||||
fn schedule_post_switch_success(
|
||||
profile_id: SmartString,
|
||||
success: bool,
|
||||
notify: bool,
|
||||
task_id: u64,
|
||||
) {
|
||||
AsyncHandler::spawn(move || async move {
|
||||
handle::Handle::notify_profile_switch_finished(
|
||||
profile_id.clone(),
|
||||
success,
|
||||
notify,
|
||||
task_id,
|
||||
);
|
||||
if notify && success {
|
||||
handle::Handle::notice_message("info", "Profile Switched");
|
||||
}
|
||||
schedule_close_connections(profile_id);
|
||||
});
|
||||
}
|
||||
|
||||
pub(super) fn describe_panic_payload(payload: &(dyn Any + Send)) -> String {
|
||||
if let Some(message) = payload.downcast_ref::<&str>() {
|
||||
(*message).to_string()
|
||||
|
||||
@@ -4,6 +4,7 @@ use crate::{
|
||||
config::{Config, IProfiles, profiles::profiles_save_file_safe},
|
||||
core::{CoreManager, handle, tray::Tray},
|
||||
logging,
|
||||
process::AsyncHandler,
|
||||
utils::logging::Type,
|
||||
};
|
||||
use futures::FutureExt;
|
||||
@@ -316,6 +317,8 @@ impl SwitchStateMachine {
|
||||
Err(_) => CoreUpdateOutcome::Timeout,
|
||||
};
|
||||
|
||||
self.ctx.release_locks();
|
||||
|
||||
Ok(SwitchState::Finalize(outcome))
|
||||
}
|
||||
|
||||
@@ -334,12 +337,18 @@ impl SwitchStateMachine {
|
||||
"Configuration update succeeded, sequence: {}",
|
||||
self.ctx.sequence()
|
||||
);
|
||||
match time::timeout(CONFIG_APPLY_TIMEOUT, async {
|
||||
Config::profiles().await.apply();
|
||||
let apply_result = time::timeout(CONFIG_APPLY_TIMEOUT, async {
|
||||
AsyncHandler::spawn_blocking(|| {
|
||||
futures::executor::block_on(async {
|
||||
Config::profiles().await.apply();
|
||||
});
|
||||
})
|
||||
.await
|
||||
})
|
||||
.await
|
||||
{
|
||||
Ok(()) => {}
|
||||
.await;
|
||||
|
||||
match apply_result {
|
||||
Ok(_) => {}
|
||||
Err(_) => {
|
||||
logging!(
|
||||
warn,
|
||||
@@ -366,64 +375,59 @@ impl SwitchStateMachine {
|
||||
);
|
||||
}
|
||||
|
||||
match time::timeout(TRAY_UPDATE_TIMEOUT, Tray::global().update_tooltip()).await {
|
||||
Ok(Ok(())) => {}
|
||||
Ok(Err(err)) => {
|
||||
logging!(
|
||||
warn,
|
||||
Type::Cmd,
|
||||
"Failed to update tray tooltip asynchronously: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
Err(_) => {
|
||||
logging!(
|
||||
warn,
|
||||
Type::Cmd,
|
||||
"Updating tray tooltip timed out after {:?}",
|
||||
TRAY_UPDATE_TIMEOUT
|
||||
);
|
||||
}
|
||||
let update_tooltip = time::timeout(TRAY_UPDATE_TIMEOUT, async {
|
||||
Tray::global().update_tooltip().await
|
||||
})
|
||||
.await;
|
||||
if update_tooltip.is_err() {
|
||||
logging!(
|
||||
warn,
|
||||
Type::Cmd,
|
||||
"Updating tray tooltip timed out after {:?}",
|
||||
TRAY_UPDATE_TIMEOUT
|
||||
);
|
||||
} else if let Ok(Err(err)) = update_tooltip {
|
||||
logging!(
|
||||
warn,
|
||||
Type::Cmd,
|
||||
"Failed to update tray tooltip asynchronously: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
|
||||
match time::timeout(TRAY_UPDATE_TIMEOUT, Tray::global().update_menu()).await {
|
||||
Ok(Ok(())) => {}
|
||||
Ok(Err(err)) => {
|
||||
logging!(
|
||||
warn,
|
||||
Type::Cmd,
|
||||
"Failed to update tray menu asynchronously: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
Err(_) => {
|
||||
logging!(
|
||||
warn,
|
||||
Type::Cmd,
|
||||
"Updating tray menu timed out after {:?}",
|
||||
TRAY_UPDATE_TIMEOUT
|
||||
);
|
||||
}
|
||||
let update_menu = time::timeout(TRAY_UPDATE_TIMEOUT, async {
|
||||
Tray::global().update_menu().await
|
||||
})
|
||||
.await;
|
||||
if update_menu.is_err() {
|
||||
logging!(
|
||||
warn,
|
||||
Type::Cmd,
|
||||
"Updating tray menu timed out after {:?}",
|
||||
TRAY_UPDATE_TIMEOUT
|
||||
);
|
||||
} else if let Ok(Err(err)) = update_menu {
|
||||
logging!(
|
||||
warn,
|
||||
Type::Cmd,
|
||||
"Failed to update tray menu asynchronously: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
|
||||
match time::timeout(SAVE_PROFILES_TIMEOUT, profiles_save_file_safe()).await {
|
||||
Ok(Ok(())) => {}
|
||||
Ok(Err(err)) => {
|
||||
logging!(
|
||||
warn,
|
||||
Type::Cmd,
|
||||
"Failed to persist configuration file asynchronously: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
Err(_) => {
|
||||
logging!(
|
||||
warn,
|
||||
Type::Cmd,
|
||||
"Persisting configuration file timed out after {:?}",
|
||||
SAVE_PROFILES_TIMEOUT
|
||||
);
|
||||
}
|
||||
let save_future = AsyncHandler::spawn_blocking(|| {
|
||||
futures::executor::block_on(async { profiles_save_file_safe().await })
|
||||
});
|
||||
if time::timeout(SAVE_PROFILES_TIMEOUT, save_future)
|
||||
.await
|
||||
.is_err()
|
||||
{
|
||||
logging!(
|
||||
warn,
|
||||
Type::Cmd,
|
||||
"Persisting configuration file timed out after {:?}",
|
||||
SAVE_PROFILES_TIMEOUT
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(current) = self.ctx.new_profile_for_event.clone() {
|
||||
@@ -620,6 +624,11 @@ impl SwitchContext {
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn release_locks(&mut self) {
|
||||
self.core_guard = None;
|
||||
self.switch_scope = None;
|
||||
}
|
||||
}
|
||||
|
||||
enum SwitchState {
|
||||
|
||||
Reference in New Issue
Block a user