]> git.proxmox.com Git - rustc.git/blame - vendor/salsa/book/src/common_patterns/on_demand_inputs.md
New upstream version 1.48.0+dfsg1
[rustc.git] / vendor / salsa / book / src / common_patterns / on_demand_inputs.md
CommitLineData
f035d41b
XL
1# On-Demand (Lazy) Inputs
2
3Salsa input queries work best if you can easily provide all of the inputs upfront.
4However sometimes the set of inputs is not known beforehand.
5
6A typical example is reading files from disk.
7While it is possible to eagerly scan a particular directory and create an in-memory file tree in a salsa input query, a more straight-forward approach is to read the files lazily.
8That is, when someone requests the text of a file for the first time:
9
101. Read the file from disk and cache it.
112. Setup a file-system watcher for this path.
123. Invalidate the cached file once the watcher sends a change notification.
13
14This is possible to achieve in salsa, using a derived query and `report_synthetic_read` and `invalidate` queries.
15The setup looks roughly like this:
16
17```rust,ignore
18#[salsa::query_group(VfsDatabaseStorage)]
19trait VfsDatabase: salsa::Database + FileWatcher {
20 fn read(&self, path: PathBuf) -> String;
21}
22
23trait FileWatcher {
24 fn watch(&self, path: &Path);
25 fn did_change_file(&mut self, path: &Path);
26}
27
3dfed10e 28fn read(db: &dyn salsa::Database, path: PathBuf) -> String {
f035d41b
XL
29 db.salsa_runtime()
30 .report_synthetic_read(salsa::Durability::LOW);
31 db.watch(&path);
32 std::fs::read_to_string(&path).unwrap_or_default()
33}
34
35#[salsa::database(VfsDatabaseStorage)]
36struct MyDatabase { ... }
37
38impl FileWatcher for MyDatabase {
39 fn watch(&self, path: &Path) { ... }
40 fn did_change_file(&mut self, path: &Path) {
41 self.query_mut(ReadQuery).invalidate(path);
42 }
43}
44```
45
46* We declare the query as a derived query (which is the default).
47* In the query implementation, we don't call any other query and just directly read file from disk.
48* Because the query doesn't read any inputs, it will be assigned a `HIGH` durability by default, which we override with `report_synthetic_read`.
49* The result of the query is cached, and we must call `invalidate` to clear this cache.