Skip to content

Commit 3f71114

Browse files
committed
[IMP] use workDoneProgress to report loading progression and git lock events
1 parent ad4ce49 commit 3f71114

File tree

2 files changed

+83
-4
lines changed

2 files changed

+83
-4
lines changed

server/src/core/odoo.rs

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ use std::ffi::OsStr;
1515
use std::rc::{Rc, Weak};
1616
use std::sync::atomic::{AtomicBool, Ordering};
1717
use std::sync::Arc;
18-
use std::time::Instant;
18+
use std::time::{Duration, Instant};
1919
use lsp_server::ResponseError;
20+
use lsp_types::notification::{Notification, Progress};
21+
use lsp_types::request::WorkDoneProgressCreate;
2022
use lsp_types::*;
2123
use request::{RegisterCapability, Request, WorkspaceConfiguration};
2224
use serde_json::Value;
@@ -73,6 +75,7 @@ pub struct SyncOdoo {
7375
pub main_entry_tree: Vec<OYarn>,
7476
pub stubs_dirs: Vec<String>,
7577
pub stdlib_dir: String,
78+
pub progress_token: i32,
7679
file_mgr: Rc<RefCell<FileMgr>>,
7780
pub modules: HashMap<OYarn, Weak<RefCell<Symbol>>>,
7881
pub models: HashMap<OYarn, Rc<RefCell<Model>>>,
@@ -110,6 +113,7 @@ impl SyncOdoo {
110113
has_odoo_main_entry: false,
111114
has_valid_python: false,
112115
main_entry_tree: vec![],
116+
progress_token: 0,
113117
file_mgr: Rc::new(RefCell::new(FileMgr::new())),
114118
stubs_dirs: SyncOdoo::default_stubs(),
115119
stdlib_dir: SyncOdoo::default_stdlib(),
@@ -601,6 +605,22 @@ impl SyncOdoo {
601605
session.sync_odoo.must_reload_paths.retain(|x| x.0.upgrade().is_some());
602606
}
603607

608+
fn start_reporting(session: &mut SessionInfo) {
609+
session.sync_odoo.progress_token += 1;
610+
let _ = session.send_request::<WorkDoneProgressCreateParams, ()>(WorkDoneProgressCreate::METHOD, WorkDoneProgressCreateParams {
611+
token: ProgressToken::Number(session.sync_odoo.progress_token)
612+
});
613+
session.send_notification(Progress::METHOD, ProgressParams {
614+
token: ProgressToken::Number(session.sync_odoo.progress_token),
615+
value: ProgressParamsValue::WorkDone(WorkDoneProgress::Begin(WorkDoneProgressBegin {
616+
title: "Odoo: Indexing".to_string(),
617+
cancellable: Some(false),
618+
message: None,
619+
percentage: None,
620+
}))
621+
});
622+
}
623+
604624
pub fn process_rebuilds(session: &mut SessionInfo, no_validation: bool) -> bool {
605625
session.sync_odoo.interrupt_rebuild.store(false, Ordering::SeqCst);
606626
if session.sync_odoo.watched_file_updates > MAX_WATCHED_FILES_UPDATES_BEFORE_RESTART {
@@ -611,11 +631,31 @@ impl SyncOdoo {
611631
let mut already_arch_rebuilt: HashSet<Tree> = HashSet::new();
612632
let mut already_arch_eval_rebuilt: HashSet<Tree> = HashSet::new();
613633
let mut already_validation_rebuilt: HashSet<Tree> = HashSet::new();
634+
635+
//workdone progress
636+
let mut last_update_status = Instant::now() - Duration::from_secs(10);
637+
let mut is_reporting_progress = false;
638+
if !session.sync_odoo.rebuild_arch.is_empty() || !session.sync_odoo.rebuild_arch_eval.is_empty() || !session.sync_odoo.rebuild_validation.is_empty() {
639+
is_reporting_progress = true;
640+
SyncOdoo::start_reporting(session);
641+
}
614642
trace!("Starting rebuild: {:?} - {:?} - {:?}", session.sync_odoo.rebuild_arch.len(), session.sync_odoo.rebuild_arch_eval.len(), session.sync_odoo.rebuild_validation.len());
615643
while !session.sync_odoo.need_rebuild && (!session.sync_odoo.rebuild_arch.is_empty() || !session.sync_odoo.rebuild_arch_eval.is_empty() || !session.sync_odoo.rebuild_validation.is_empty()) {
616644
if DEBUG_THREADS {
617645
trace!("remains: {:?} - {:?} - {:?}", session.sync_odoo.rebuild_arch.len(), session.sync_odoo.rebuild_arch_eval.len(), session.sync_odoo.rebuild_validation.len());
618646
}
647+
let queue_size = session.sync_odoo.rebuild_arch.len() * 3 + session.sync_odoo.rebuild_arch_eval.len() * 2 + session.sync_odoo.rebuild_validation.len();
648+
if is_reporting_progress && (Instant::now() - last_update_status) > Duration::from_millis(200) {
649+
last_update_status = Instant::now();
650+
session.send_notification(Progress::METHOD, ProgressParams {
651+
token: ProgressToken::Number(session.sync_odoo.progress_token),
652+
value: ProgressParamsValue::WorkDone(WorkDoneProgress::Report(WorkDoneProgressReport {
653+
cancellable: Some(false),
654+
message: Some(format!("{} items remaining", queue_size)),
655+
percentage: None,
656+
}))
657+
});
658+
}
619659
if session.sync_odoo.terminate_rebuild.load(Ordering::SeqCst){
620660
info!("Terminating rebuilds due to server shutdown");
621661
return false;
@@ -662,6 +702,14 @@ impl SyncOdoo {
662702
if no_validation {
663703
session.request_delayed_rebuild();
664704
session.sync_odoo.add_to_validations(sym_rc.clone());
705+
if is_reporting_progress {
706+
session.send_notification(Progress::METHOD, ProgressParams {
707+
token: ProgressToken::Number(session.sync_odoo.progress_token),
708+
value: ProgressParamsValue::WorkDone(WorkDoneProgress::End(WorkDoneProgressEnd {
709+
message: None,
710+
}))
711+
});
712+
}
665713
return true;
666714
}
667715
}
@@ -686,6 +734,14 @@ impl SyncOdoo {
686734
}
687735
session.sync_odoo.import_cache = None;
688736
session.sync_odoo.watched_file_updates = 0;
737+
if is_reporting_progress {
738+
session.send_notification(Progress::METHOD, ProgressParams {
739+
token: ProgressToken::Number(session.sync_odoo.progress_token),
740+
value: ProgressParamsValue::WorkDone(WorkDoneProgress::End(WorkDoneProgressEnd {
741+
message: None,
742+
}))
743+
});
744+
}
689745
trace!("Leaving rebuild with remaining tasks: {:?} - {:?} - {:?}", session.sync_odoo.rebuild_arch.len(), session.sync_odoo.rebuild_arch_eval.len(), session.sync_odoo.rebuild_validation.len());
690746
true
691747
}

server/src/threads.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ pub enum DelayedProcessingMessage {
169169
EXIT, //exit the thread
170170
}
171171

172-
pub fn restart_server(sync_odoo: &Arc<Mutex<SyncOdoo>>, sender_session: &Sender<Message>, receiver_session: &Receiver<Message>, delayed_process_sender: &Sender<DelayedProcessingMessage>) {
172+
fn restart_server(sync_odoo: &Arc<Mutex<SyncOdoo>>, sender_session: &Sender<Message>, receiver_session: &Receiver<Message>, delayed_process_sender: &Sender<DelayedProcessingMessage>) {
173173
let message = "Too many requests, possible change of branch, restarting Odoo LS";
174174
info!(message);
175175
{
@@ -181,11 +181,25 @@ pub fn restart_server(sync_odoo: &Arc<Mutex<SyncOdoo>>, sender_session: &Sender<
181181
noqas_stack: vec![],
182182
current_noqa: NoqaInfo::None,
183183
};
184-
// Drain channel before resetting
185184
session.send_notification("$Odoo/restartNeeded", ());
186185
}
187186
}
188187

188+
fn notify_git_lock(sync_odoo: &Arc<Mutex<SyncOdoo>>, sender_session: &Sender<Message>, receiver_session: &Receiver<Message>, delayed_process_sender: &Sender<DelayedProcessingMessage>, status: &str) {
189+
{
190+
let session = SessionInfo{
191+
sender: sender_session.clone(),
192+
receiver: receiver_session.clone(),
193+
sync_odoo: &mut sync_odoo.lock().unwrap(),
194+
delayed_process_sender: Some(delayed_process_sender.clone()),
195+
noqas_stack: vec![],
196+
current_noqa: NoqaInfo::None,
197+
};
198+
error!("Git index lock detected, notifying client: {}", status);
199+
session.send_notification("$Odoo/loadingStatusUpdate", status);
200+
}
201+
}
202+
189203
pub fn delayed_changes_process_thread(sender_session: Sender<Message>, receiver_session: Receiver<Message>, receiver: Receiver<DelayedProcessingMessage>, sync_odoo: Arc<Mutex<SyncOdoo>>, delayed_process_sender: Sender<DelayedProcessingMessage>) {
190204
const MAX_DELAY: u64 = 15000;
191205
const MIN_DELAY: u64 = 1000;
@@ -199,11 +213,20 @@ pub fn delayed_changes_process_thread(sender_session: Sender<Message>, receiver_
199213
// Check if immediate reaction is needed, else add the message to the list
200214
match msg {
201215
Ok(DelayedProcessingMessage::RESTART) => {
202-
if let Some(main_entry_path) = sync_odoo.lock().unwrap().config.odoo_path.as_ref().cloned() {
216+
let main_entry_path = sync_odoo.lock().unwrap().config.odoo_path.as_ref().cloned(); //avoid keeping lock
217+
if let Some(main_entry_path) = main_entry_path {
203218
let index_lock_path = PathBuf::from(main_entry_path).join(".git").join("index.lock");
219+
let mut notified = false;
204220
while index_lock_path.exists(){
221+
if !notified {
222+
notify_git_lock(&sync_odoo, &sender_session, &receiver_session, &delayed_process_sender, "git_locked");
223+
notified = true;
224+
}
205225
std::thread::sleep(std::time::Duration::from_secs(1));
206226
}
227+
if notified {
228+
notify_git_lock(&sync_odoo, &sender_session, &receiver_session, &delayed_process_sender, "stop");
229+
}
207230
}
208231
if !waiting_restart {
209232
waiting_restart = true;

0 commit comments

Comments
 (0)