{"action":"created","issue":{"url":"https://api.github.com/repos/rust-analyzer/rust-analyzer/issues/62","repository_url":"https://api.github.com/repos/rust-analyzer/rust-analyzer","labels_url":"https://api.github.com/repos/rust-analyzer/rust-analyzer/issues/62/labels{/name}","comments_url":"https://api.github.com/repos/rust-analyzer/rust-analyzer/issues/62/comments","events_url":"https://api.github.com/repos/rust-analyzer/rust-analyzer/issues/62/events","html_url":"https://github.com/rust-analyzer/rust-analyzer/issues/62","id":358288137,"node_id":"MDU6SXNzdWUzNTgyODgxMzc=","number":62,"title":"Adapt Salsa (red-green) algorithm to IDE use-case","user":{"login":"matklad","id":1711539,"node_id":"MDQ6VXNlcjE3MTE1Mzk=","avatar_url":"https://avatars3.githubusercontent.com/u/1711539?v=4","gravatar_id":"","url":"https://api.github.com/users/matklad","html_url":"https://github.com/matklad","followers_url":"https://api.github.com/users/matklad/followers","following_url":"https://api.github.com/users/matklad/following{/other_user}","gists_url":"https://api.github.com/users/matklad/gists{/gist_id}","starred_url":"https://api.github.com/users/matklad/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matklad/subscriptions","organizations_url":"https://api.github.com/users/matklad/orgs","repos_url":"https://api.github.com/users/matklad/repos","events_url":"https://api.github.com/users/matklad/events{/privacy}","received_events_url":"https://api.github.com/users/matklad/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2018-09-08T11:38:35Z","updated_at":"2018-10-25T14:37:05Z","closed_at":null,"author_association":"COLLABORATOR","body":"rustc uses the red-green algorithm to implement on-demand and incremental compilation: https://rust-lang-nursery.github.io/rustc-guide/incremental-compilation.html, and it looks like the perfect basis for Code Analyzer support as well.\r\n\r\nHowever, there's a fundamental difference between how rustc does red-green, and how Code Analyzer works.\r\n\r\nCommand-line compiler operates in a sequence of invocations, so there are distinctly separate phases of updating the root data and calculating queries. \r\n\r\nIn Code Analyzer, query evaluation and data modification can happen concurrently. Consider the following sequence of events\r\n\r\n* user types something in `foo.rs`\r\n* we start a job to do reparsing and basic syntax-based highlighting\r\n* re parsing finishes\r\n* we start a job to infer types inside `foo.rs` and present errors\r\n* user types something in other file, `bar.rs`.\r\n\r\nThat is, we have an in-progress query on our hands, and a set of changes to apply. What we want is\r\n\r\n* to apply changes as fast as possible\r\n* preferably, not to loose reparsing info for `foo.rs`\r\n* preferably, cleanly cancel an in-flight request.\r\n\r\nHere are some options to deal with the problem\r\n\r\n* we can wrap QueryEngine in an `RwLock`, so that all all request acquire and hold read lock for the duration of the request, modifying the root facts requires acquiring a write lock. When we receive an update request, we cancel all pending requests, wait for them to finish and apply updates. This is the approach used in IntelliJ. It should be very efficient in the total amount of work done, but can cause slow response if cancellation is not threaded throughout all of the requests.\r\n\r\n* we can wrap QueryEngine in an `Arc` and use `Arc::make_mut` to apply updates. This requires QueryEngine to be cheaply clone (so, `im::HashMap` instead of `std::HashMap`), and needs an intricate operation of cloning the database as queries are storing new results into it.\r\n\r\n* we can implement the first solution by making use of existing interior mutability in QueryEngine. Specifically, we can store an atomic timestamp, which is incremented before we apply changes. When we execute queries, we check the current timestamp and auto-cancel the request, if it is greater than the request-start time.\r\n\r\nIt's interesting that these solutions are not optimal in a sense that if the current query deals exclusively with `foo.rs` file, and modifications apply only to `bar.rs` file, we loos the results of the query, although they are not affected by modification. "},"comment":{"url":"https://api.github.com/repos/rust-analyzer/rust-analyzer/issues/comments/433076533","html_url":"https://github.com/rust-analyzer/rust-analyzer/issues/62#issuecomment-433076533","issue_url":"https://api.github.com/repos/rust-analyzer/rust-analyzer/issues/62","id":433076533,"node_id":"MDEyOklzc3VlQ29tbWVudDQzMzA3NjUzMw==","user":{"login":"aochagavia","id":5196584,"node_id":"MDQ6VXNlcjUxOTY1ODQ=","avatar_url":"https://avatars1.githubusercontent.com/u/5196584?v=4","gravatar_id":"","url":"https://api.github.com/users/aochagavia","html_url":"https://github.com/aochagavia","followers_url":"https://api.github.com/users/aochagavia/followers","following_url":"https://api.github.com/users/aochagavia/following{/other_user}","gists_url":"https://api.github.com/users/aochagavia/gists{/gist_id}","starred_url":"https://api.github.com/users/aochagavia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aochagavia/subscriptions","organizations_url":"https://api.github.com/users/aochagavia/orgs","repos_url":"https://api.github.com/users/aochagavia/repos","events_url":"https://api.github.com/users/aochagavia/events{/privacy}","received_events_url":"https://api.github.com/users/aochagavia/received_events","type":"User","site_admin":false},"created_at":"2018-10-25T14:37:05Z","updated_at":"2018-10-25T14:37:05Z","author_association":"COLLABORATOR","body":"Should this be moved to https://github.com/salsa-rs/salsa now we have finally migrated to it?"}}
{"actor":{"display_login":"aochagavia"}}