Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Analyzing progress notifications #44

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

Arcticae
Copy link
Member

Based off this PR we can start implementing tests (like currently we can wait for project update + the diagnostics finish and it should work fine)

@Arcticae Arcticae force-pushed the feature/analyzing-progress-notifications branch 2 times, most recently from ae728b8 to bcd6a77 Compare December 18, 2024 13:33
src/lang/diagnostics/mod.rs Outdated Show resolved Hide resolved
@@ -26,7 +26,7 @@ pub struct Client<'s> {
pub(super) requester: Requester<'s>,
}

#[derive(Clone)]
#[derive(Clone, Debug)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Suggested change
#[derive(Clone, Debug)]
#[derive(Clone)]

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's included in the new Controller which needs to be Debug as well because of ProcMacroClient being Debug

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe custom impl on ProcMacroClient would be better in this case? This does not make sense to debug this struct

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not done

src/state.rs Outdated
);

let diagnostics_controller =
DiagnosticsController::new(notifier.clone(), analysis_progress_controller.clone());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please dont pass AnalysisProgressController everywhere, split it into 2 parts where one lives on the main thread/special thread and second can be used in other places, this will also help splitting its interface.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done - pls let me know if that's what you meant

src/state.rs Outdated Show resolved Hide resolved
/// Uses information provided from other controllers (diagnostics controller, procmacro controller)
/// to assess if diagnostics are in fact calculated.
#[derive(Debug, Clone)]
pub struct AnalysisProgressController {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we get flow explanation here? like in ProcMacroController

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do although i think it's nicely explained here in the docstrings

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBD Still - i would like to finalize business logic first if that's OK so i don't have to update this flowchart

@Arcticae Arcticae force-pushed the feature/analyzing-progress-notifications branch from bcd6a77 to 2a2bc04 Compare December 18, 2024 13:49
Co-authored-by: Piotr Figiela <77412592+Draggu@users.noreply.github.com>
Signed-off-by: Tomasz Rejowski <34059895+Arcticae@users.noreply.github.com>
src/state.rs Outdated
}
}

pub struct Beacon<T> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a specific reason why are you wrapping T here?

can't this be a valueless object that is kept as a field in the old StateSnapshot? It would still be dropped whenever StateSnapshot is

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I resigned from the "on-drop" behaviour (because of lack of information when the analysis actually finished on a thread vs. the thread was cancelled)
  2. I can do this without wrapping - no problem there i think (discussion here)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I resigned from the "on-drop" behaviour (because of lack of information when the analysis actually finished on a thread vs. the thread was cancelled)

Can we add a comment about it somewhere near that?

Copy link
Member Author

@Arcticae Arcticae Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would i add a comment about something that i didn't implement

@@ -26,7 +26,7 @@ pub struct Client<'s> {
pub(super) requester: Requester<'s>,
}

#[derive(Clone)]
#[derive(Clone, Debug)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not done

}
}
/// Struct which allows setting a callback - which can be triggered afterward
/// by the function which has the reference.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reference to what?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reference to the thing that i'm talking about - the struct

/// Struct which allows setting a callback - which can be triggered afterward
/// by the function which has the reference.
#[derive(Default)]
pub struct Beacon {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a standard name for this pattern? Isn't Callback with set and execute methods better?


pub fn signal(&mut self) {
if let Some(hook) = self.signal_hook.take() {
hook(); // call the hook
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is useless

self.signal_hook = Some(Box::new(drop_hook));
}

pub fn signal(&mut self) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

signal_and_clear_hook?

Comment on lines +164 to +180
/// Notifies about diagnostics generation which is beginning to calculate
#[derive(Debug)]
pub struct DiagnosticsCalculationStart;

impl Notification for DiagnosticsCalculationStart {
type Params = ();
const METHOD: &'static str = "cairo/diagnosticsCalculationStart";
}

/// Notifies about diagnostics generation which ended calculating
#[derive(Debug)]
pub struct DiagnosticsCalculationFinish;

impl Notification for DiagnosticsCalculationFinish {
type Params = ();
const METHOD: &'static str = "cairo/diagnosticsCalculationFinish";
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idk if it shouldn't go to lsp/ext.rs for consistency

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know why not place it near the usage tbh

src/state.rs Show resolved Hide resolved
}

impl Beacon {
// Set the drop hook
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dot.

Btw it doesn't set the drop hook, it is not done on Drop.

src/ide/analysis_progress.rs Show resolved Hide resolved
.field("id_generator", &self.id_generator)
.field("requests_params", &self.requests_params)
.field("error_channel", &self.error_channel)
.finish()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.finish()
.finish_non_exhaustive()

}

impl Beacon {
// Set the drop hook
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe note here that it is disposable?

src/state.rs Show resolved Hide resolved
controller: AnalysisProgressController,
}

impl AnalysisProgressTracker {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can split it for proc macros / diagnostics so interface is clear there, also it does not have to store whole controller (and should not if it possible, if not then maybe controller itself is ok).

}

/// Allows to set the procmacro configuration to whatever is in the config, upon loading it.
pub fn set_procmacros_enabled(&self, value: bool) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub fn set_procmacros_enabled(&self, value: bool) {
pub fn on_config_change(&self, config: &Config) {

More future proof and it is clear where this info is coming from.

let id_generator = Arc::new(IdGenerator::default());
Self {
notifier,
id_generator: id_generator.clone(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why clone here, just generate unique_id before the struct constructor expr

Comment on lines +116 to +118
pub fn get_generation_id(&self) -> u64 {
self.generation_id.load(Ordering::SeqCst)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used in one place, just inline it imo

}

pub fn clear_active_snapshots(&self) {
let active_snapshots_ref = self.active_snapshots.clone();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need to clone here?

@@ -142,6 +150,7 @@ impl ProcMacroClient {
match self.send_request_untracked::<M>(id, &params) {
Ok(()) => {
requests_params.insert(id, map(params));
self.analysis_progress_tracker.register_procmacro_request();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that there is a small chance that a yet alive snapshot from previous diagnostics calculation was already in db.get_attribute_expansion before its cancellation. It will still call this method and possibly register proc macro request in analysis tracker AFTER track_analysis is called to start tracking the new diagnostics batch. It can cause us to never finish waiting for diagnostics in tests, since:

  • the next batch won't be scheduled
  • we will always think there is some proc macro yet to resolve while it may not be

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants