on master help sign in
improve reliability of shutdown
commitcb23399dee723cec67f1a04dbe6514dfddfd7f5f authorSkyler Hawthorne <skyler@dead10ck.com> dateSat 9 Jul 2022, 22:39 (4 years ago) parentb8a07f7
4 files changed+80−25
helix-term/src/application.rs+52−20 helix-term/src/commands/typed.rs+7−1 helix-view/src/document.rs+15−2 helix-view/src/editor.rs+6−2
helix-term/src/application.rs+52−20
@@ -937,26 +937,26 @@ impl Application {
937937
938938 self.event_loop(input_stream).await;
939939
940− let mut save_errs = Vec::new();
941−
942− for doc in self.editor.documents_mut() {
943− if let Some(Err(err)) = doc.close().await {
944− save_errs.push((
945− doc.path()
946− .map(|path| path.to_string_lossy().into_owned())
947− .unwrap_or_else(|| "".into()),
948− err,
949− ));
950− }
951− }
940+ // let mut save_errs = Vec::new();
941+
942+ // for doc in self.editor.documents_mut() {
943+ // if let Some(Err(err)) = doc.close().await {
944+ // save_errs.push((
945+ // doc.path()
946+ // .map(|path| path.to_string_lossy().into_owned())
947+ // .unwrap_or_else(|| "".into()),
948+ // err,
949+ // ));
950+ // }
951+ // }
952952
953953 let close_err = self.close().await.err();
954954 restore_term()?;
955955
956− for (path, err) in save_errs {
957− self.editor.exit_code = 1;
958− eprintln!("Error closing '{}': {}", path, err);
959− }
956+ // for (path, err) in save_errs {
957+ // self.editor.exit_code = 1;
958+ // eprintln!("Error closing '{}': {}", path, err);
959+ // }
960960
961961 if let Some(err) = close_err {
962962 self.editor.exit_code = 1;
@@ -967,12 +967,44 @@ impl Application {
967967 }
968968
969969 pub async fn close(&mut self) -> anyhow::Result<()> {
970− self.jobs.finish().await?;
970+ // [NOTE] we intentionally do not return early for errors because we
971+ // want to try to run as much cleanup as we can, regardless of
972+ // errors along the way
971973
972− if self.editor.close_language_servers(None).await.is_err() {
973− log::error!("Timed out waiting for language servers to shutdown");
974+ let mut result = match self.jobs.finish().await {
975+ Ok(_) => Ok(()),
976+ Err(err) => {
977+ log::error!("Error executing job: {}", err);
978+ Err(err)
979+ }
974980 };
975981
976− Ok(())
982+ for doc in self.editor.documents_mut() {
983+ if let Some(save_result) = doc.close().await {
984+ result = match save_result {
985+ Ok(_) => result,
986+ Err(err) => {
987+ if let Some(path) = doc.path() {
988+ log::error!(
989+ "Error saving document '{}': {}",
990+ path.to_string_lossy(),
991+ err
992+ );
993+ }
994+ Err(err)
995+ }
996+ };
997+ }
998+ }
999+
1000+ match self.editor.close_language_servers(None).await {
1001+ Ok(_) => result,
1002+ Err(_) => {
1003+ log::error!("Timed out waiting for language servers to shutdown");
1004+ Err(anyhow::format_err!(
1005+ "Timed out waiting for language servers to shutdown"
1006+ ))
1007+ }
1008+ }
9771009 }
9781010}
helix-term/src/commands/typed.rs+7−1
@@ -1,5 +1,7 @@
11use std::ops::Deref;
22
3+use crate::job::Job;
4+
35use super::*;
46
57use helix_view::{
@@ -19,6 +21,8 @@ pub struct TypableCommand {
1921}
2022
2123fn quit(cx: &mut compositor::Context, args: &[Cow<str>], event: PromptEvent) -> anyhow::Result<()> {
24+ log::info!("quitting...");
25+
2226 if event != PromptEvent::Validate {
2327 return Ok(());
2428 }
@@ -274,7 +278,7 @@ fn write_impl(
274278 doc.auto_format().map(|fmt| {
275279 let shared = fmt.shared();
276280 let callback = make_format_callback(doc.id(), doc.version(), shared.clone());
277− jobs.callback(callback);
281+ jobs.add(Job::with_callback(callback).wait_before_exiting());
278282 shared
279283 })
280284 } else {
@@ -512,8 +516,10 @@ fn write_quit(
512516 }
513517
514518 write_impl(cx, args.first(), false)?;
519+
515520 let doc = doc_mut!(cx.editor);
516521
522+ tokio::task::block_in_place(|| helix_lsp::block_on(cx.jobs.finish()))?;
517523 tokio::task::block_in_place(|| helix_lsp::block_on(doc.try_flush_saves()))
518524 .map(|result| result.map(|_| ()))
519525 .unwrap_or(Ok(()))?;
helix-view/src/document.rs+15−2
@@ -551,6 +551,11 @@ impl Document {
551551 bail!("saves are closed for this document!");
552552 }
553553
554+ log::debug!(
555+ "submitting save of doc '{:?}'",
556+ self.path().map(|path| path.to_string_lossy())
557+ );
558+
554559 // we clone and move text + path into the future so that we asynchronously save the current
555560 // state without blocking any further edits.
556561 let mut text = self.text().clone();
@@ -695,7 +700,14 @@ impl Document {
695700 self.set_last_saved_revision(event.revision);
696701 false
697702 }
698− Err(_) => true,
703+ Err(err) => {
704+ log::error!(
705+ "error saving document {:?}: {}",
706+ self.path().map(|path| path.to_string_lossy()),
707+ err
708+ );
709+ true
710+ }
699711 };
700712
701713 final_result = Some(save_event);
@@ -1072,7 +1084,8 @@ impl Document {
10721084 let current_revision = history.current_revision();
10731085 self.history.set(history);
10741086 log::debug!(
1075− "modified - last saved: {}, current: {}",
1087+ "id {} modified - last saved: {}, current: {}",
1088+ self.id,
10761089 self.last_saved_revision,
10771090 current_revision
10781091 );
helix-view/src/editor.rs+6−2
@@ -816,12 +816,16 @@ impl Editor {
816816
817817 #[inline]
818818 pub fn set_status<T: Into<Cow<'static, str>>>(&mut self, status: T) {
819− self.status_msg = Some((status.into(), Severity::Info));
819+ let status = status.into();
820+ log::debug!("editor status: {}", status);
821+ self.status_msg = Some((status, Severity::Info));
820822 }
821823
822824 #[inline]
823825 pub fn set_error<T: Into<Cow<'static, str>>>(&mut self, error: T) {
824− self.status_msg = Some((error.into(), Severity::Error));
826+ let error = error.into();
827+ log::error!("editor error: {}", error);
828+ self.status_msg = Some((error, Severity::Error));
825829 }
826830
827831 #[inline]