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

Add Handle::into_inner method #531

Merged
merged 1 commit into from
Jul 27, 2024
Merged

Add Handle::into_inner method #531

merged 1 commit into from
Jul 27, 2024

Conversation

MichaReiser
Copy link
Contributor

@MichaReiser MichaReiser commented Jul 26, 2024

This PR adds a into_inner function to Handle.

Being able to go back to the database can be useful for methods that take a Database as argument but have to create a Handle because they run concurrent code.
It is then desired that the method can return a Database to avoid that the entire code base has to use a Handle<Db>.

Example:

    #[allow(clippy::print_stderr)]
    fn run(mut self, db: RootDatabase) -> RootDatabase {
        // Schedule the first check.
        let mut db = salsa::Handle::new(db);
        self.sender.send(MainLoopMessage::CheckWorkspace).unwrap();
        let mut revision = 0usize;

        while let Ok(message) = self.receiver.recv() {
            tracing::trace!("Main Loop: Tick");

            match message {
                MainLoopMessage::CheckWorkspace => {
                    let db = db.clone();
                    let sender = self.sender.clone();

                    // Spawn a new task that checks the workspace. This needs to be done in a separate thread
                    // to prevent blocking the main loop here.
                    rayon::spawn(move || {
                        if let Ok(result) = db.check() {
                            // Send the result back to the main loop for printing.
                            sender
                                .send(MainLoopMessage::CheckCompleted { result, revision })
                                .ok();
                        }
                    });
                }

                MainLoopMessage::CheckCompleted {
                    result,
                    revision: check_revision,
                } => {
                    if check_revision == revision {
                        eprintln!("{}", result.join("\n"));

                        if self.verbosity == Some(VerbosityLevel::Trace) {
                            eprintln!("{}", countme::get_all());
                        }
                    }

                    if self.watcher.is_none() {
                        return db.into_inner();
                    }
                }

                MainLoopMessage::ApplyChanges(changes) => {
                    revision += 1;
                    // Automatically cancels any pending queries and waits for them to complete.
                    db.get_mut().apply_changes(changes);
                    if let Some(watcher) = self.watcher.as_mut() {
                        watcher.update(&db);
                    }

                    self.sender.send(MainLoopMessage::CheckWorkspace).unwrap();
                }
                MainLoopMessage::Exit => {
                    return db.into_inner();
                }
            }
        }

        db.into_inner()
    }

Why not just pass in a Handle

This is a possibility but it leaks that the function uses concurrency internally and one also has to be careful to pass in a &mut Handle<T> and to not clone it on the call-site (which I did) because it then results in a dead lock when calling get_mut.

Copy link

netlify bot commented Jul 26, 2024

Deploy Preview for salsa-rs canceled.

Name Link
🔨 Latest commit c66f600
🔍 Latest deploy log https://app.netlify.com/sites/salsa-rs/deploys/66a35e0b2243090008d45525

@MichaReiser MichaReiser requested a review from nikomatsakis July 26, 2024 13:59
@nikomatsakis nikomatsakis added this pull request to the merge queue Jul 27, 2024
Merged via the queue into master with commit 8788180 Jul 27, 2024
7 of 8 checks passed
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.

2 participants