Skip to content

refactor: use salsa#10315

Merged
ematipico merged 17 commits into
nextfrom
feat/salsa-db
May 24, 2026
Merged

refactor: use salsa#10315
ematipico merged 17 commits into
nextfrom
feat/salsa-db

Conversation

@ematipico

@ematipico ematipico commented May 9, 2026

Copy link
Copy Markdown
Member

Summary

This is the first PR of a refactor we want to do in core. The objective is to introduce salsa.

Salsa is a framework (not a library), so we will see more and more of the workspace architecture to better fit how Salsa works.

The intention to bring Salsa into Biome is old, but years ago the framework was in a weird status, so we couldn't adopt it. A few months ago, Astral took it under their wing, and they use Salsa to power up their type-check system for Python. Salsa is also used by rust-analyzer (it was, at least). The new Salsa is battle-tested and maintained by a group of folks with an amazing reputation.

Unfortunately, the Salsa book (their docs) isn't up to date, but many concepts stayed the same. Micha, one of the current maintainers, shared this guide with me: https://hackmd.io/5ddaZLKYSVC_YTTD3SzRDw?view

The PR is semi-vibe-coded. I used a coding agent to grab as much information as possible, and I iterated the plan 4 or 5 times. Then I changed almost all of the code that it created.

How salsa works today, in Biome

I don't have all the knowledge, but the core concepts are relatively simple

We have Salsa inputs that are tagged with #[salsa::input]. These structs change outside the database. In this PR, ModuleInfo is a type that changes outside the database, and the workspace is responsible for storing it.

In our design, the Workspace is responsible for storing and evicting data. When we need to index a module, we eventually create the ModuleInfo type using salsa setters. The setter methods are automatically created via #[salsa::input]. We need to abide by them.

Salsa doesn't enforce what to store in the database, but it enforces that we store data that has Hash and PartialEq. This isn't a problem for us.

The database inside the Workspace uses a Mutex. We need to lock it when we update it i.e. it's locked when we create a ModuleInfo instance, or we update an existing one.

How the database is defined

The lowest piece of the database is biome_db. It defines one single Db trait that will be used throughout the application by those data structures that need a database to query.

The intermediate pieces are defined by those crates that need to query the database. In this PR, the module graph. We define a new trait. This is necessary because of the Rust orphan rule.

In this PR, we have the ModuleDb, which defines some methods that must be implemented by the final implementors.

The highest piece, and the final implementer of the traits, is the WorkspaceServer.

If in the future we want to add semantic data (most likely) to the database, we will implement a SemanticDb trait, and create a physical database in charge of updating the data.

One database VS Multiple databases

I don't have the answer, and we will figure it out as we go.

As for now, we have a single database for all projects. The likelihood that a project queries a path that belongs to another project is basically null, because we have the ProjectLayout, but we can evaluate the existence of a database per project.

Changes to the module graph

The module graph is now a thin layer over Salsa. Whenever we want to query the database, we use a query, which is tagged with #[salsa::tracked]. Queries must accept a database reference and a Salsa type.

All existing functions have been moved into queries.rs, and they are tracked. I had to make some changes because many of these functions were using paths as inputs.

Pros and Cons

In addition to fitting our architecture to the framework's requirements, salsa comes with its own runtime. This runtime has a performance penalty, especially for "cold" executions such as the CLI, because all data is created once and read multiple times.

However, for the Language Server (editors), the story is completely different. Nowadays, every change to a document (keystroke), triggers:

  • re-parsing (still cached until a certain point)
  • semantic model creation (from scratch; we don't cache anything)
  • [With Project lint rules] module graph update: the single module is re-evaluated from scratch.
  • [With TypeAware lint rules] we create ALL types from scratch.

We're lucky that we use a language that is fast; however, this already has some repercussions in terms of performance and memory usage.

Test Plan

Green CI.
I manually tested the build in the editor to make sure everything still works.

This is also an internal refactor, so existing things should stay as is, and the changeset isn't needed.

Docs

Not needed.

@changeset-bot

changeset-bot Bot commented May 9, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 6670947

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions github-actions Bot added A-Project Area: project A-Linter Area: linter A-Parser Area: parser A-Formatter Area: formatter A-Tooling Area: internal tools A-LSP Area: language server protocol L-JavaScript Language: JavaScript and super languages L-CSS Language: CSS and super languages L-JSON Language: JSON and super languages A-Diagnostic Area: diagnostocis L-HTML Language: HTML and super languages L-Grit Language: GritQL A-Type-Inference Area: type inference A-Resolver Area: resolver labels May 9, 2026
@codspeed-hq

codspeed-hq Bot commented May 9, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 10.29%

❌ 6 regressed benchmarks
✅ 243 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
js_analyzer[router_17129688031671448157.ts] 35.8 ms 39.3 ms -8.95%
js_analyzer[parser_13571644119461115204.ts] 124.9 ms 140.1 ms -10.84%
js_analyzer[statement_263793315104667298.ts] 114.2 ms 128.4 ms -11.07%
js_analyzer[css_16118272471217147034.js] 33 ms 36.3 ms -9.07%
js_analyzer[typescript_3735799142832611563.ts] 177.3 ms 201.8 ms -12.12%
js_analyzer[index_3894593175024091846.js] 70 ms 77.4 ms -9.61%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing feat/salsa-db (6670947) with next (69cedfa)

Open in CodSpeed

@github-actions github-actions Bot removed A-Parser Area: parser A-Formatter Area: formatter A-Tooling Area: internal tools L-Grit Language: GritQL labels May 9, 2026
@Netail

Netail commented May 10, 2026

Copy link
Copy Markdown
Member

image

@ematipico ematipico marked this pull request as ready for review May 21, 2026 16:12
@ematipico ematipico requested review from a team May 21, 2026 16:12
@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

This PR replaces the eager in-memory ModuleGraph with a Salsa-tracked ProjectDatabase (ModuleDb). It adds a new biome_db crate and workspace salsa dependency, implements ProjectDatabase and ModuleDb queries (symbols, JSDoc, CSS class traversal, import-tree builders), introduces PathInfoCache and resolver functions (resolve_js/css/html, ModuleInfoKind), and rewires analyzers, service wiring, go-to handlers, workspace server, test utilities and many tests to use module_db/ProjectDatabase.

Possibly related PRs

  • biomejs/biome#9700: Related go-to-definition and module resolution work that also moved consumers from ModuleGraph to a database-backed flow.
  • biomejs/biome#9503: Changes to the noUndeclaredClasses lint and import/class traversal logic that overlap the rule-level DB migration.

Suggested reviewers

  • dyc3
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/salsa-db

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/biome_js_analyze/src/lint/correctness/no_unresolved_imports.rs (1)

137-145: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Gate the unresolved-export check to JS modules only

find_js_exported_symbol() returns None unless the target is ModuleInfoKind::Js. The lint now passes any ModuleInfo (via ctx.module_info_for_path(resolved_path)) into has_exported_symbol(), so HTML/CSS-backed imports can get flagged as “has no export named …” / “no default export” even when they should be skipped.

Add a ModuleInfoKind::Js gate before calling find_js_exported_symbol (for crates/biome_js_analyze/src/lint/correctness/no_unresolved_imports.rs, incl. the target_info wiring around 137-145 and the has_exported_symbol path around 239-275).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/biome_js_analyze/src/lint/correctness/no_unresolved_imports.rs` around
lines 137 - 145, The lint is calling has_exported_symbol/find_js_exported_symbol
for any ModuleInfo; add a guard to only run export checks when target_info.kind
is ModuleInfoKind::Js: after obtaining target_info via
ctx.module_info_for_path(resolved_path) (and before constructing
GetUnresolvedImportsOptions and before the has_exported_symbol path), check
target_info.kind == ModuleInfoKind::Js and skip export-resolution logic (return
Vec::new() or bypass has_exported_symbol) for non-JS kinds; ensure both the
wiring around target_info (where GetUnresolvedImportsOptions is created) and the
branch that calls has_exported_symbol/find_js_exported_symbol (the code between
the existing lines ~239–275) are updated to short-circuit for non-JS
ModuleInfoKind.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/biome_module_graph/README.md`:
- Line 3: Fix the grammar in the README sentence that currently reads "A module
a is a known file that imports and exports data, which is used" by removing the
extra "a" so it reads "A module is a known file that imports and exports data,
which is used"; update the sentence in the README.md (the line containing "A
module a is...") to the corrected wording.

In `@crates/biome_module_graph/src/css_module_info/traverse.rs`:
- Around line 105-143: The loop over importers currently breaks after the first
CSS-producing parent, which prevents pushing later sibling file_path entries
onto self.stack; change the logic in traverse.rs so you do not exit the loop
early: instead of break, continue iterating so all sibling importers get pushed,
and only set self.current_css_iter if it is not already set (guard with
self.current_css_iter.is_none()) to avoid overwriting a previously chosen
iterator; keep the existing pushes to self.visited and self.stack and the
css_steps creation but replace the unconditional break with a continue and a
conditional assignment for current_css_iter.

In `@crates/biome_module_graph/src/db/queries.rs`:
- Around line 392-397: The default-reexport branch (ImportSymbol::Default) must
be guarded by seen_paths just like the Named branch to avoid infinite loops:
when you resolve reexport.import.resolved_path.as_deref() and call
db.js_module_info_for_path(path) before doing stack.push((module, symbol_name)),
check whether seen_paths already contains that path and only push (and/or insert
into seen_paths) if it is not present; apply this exact same guard in both
functions that handle exported-symbol lookup and JSDoc lookup (the other
occurrence around the second ImportSymbol::Default handling) so default
re-export cycles are short-circuited.
- Around line 180-204: The code iterates html_info.static_import_paths twice
causing duplicate CssClassStep entries; update the second loop to only iterate
dynamic imports (or otherwise exclude static_import_paths) so each import is
processed once: modify the loop that currently chains
html_info.static_import_paths.values().chain(html_info.dynamic_import_paths.values())
to only iterate html_info.dynamic_import_paths.values() and keep the same
css_module_info_for_path lookup and linked_steps.push(CssClassStep { css_path:
..., css_classes: ... }) logic to avoid duplicated CSS steps.

In `@crates/biome_module_graph/src/path_info_cache.rs`:
- Around line 50-53: The loop in while let Some(dir) = parent currently calls
self.get_or_insert(dir, fs) and breaks if that returns Some, which treats
newly-inserted entries the same as pre-existing ones and stops prepopulating
ancestors; change the logic so you first check existence with self.get(dir) (or
an existence check) and only break when the directory already exists, otherwise
call self.get_or_insert(dir, fs) to insert and continue up the ancestor chain;
update get_or_insert only if needed (or have it return a flag) so the loop can
distinguish newly-inserted vs pre-existing entries.

In `@crates/biome_service/src/workspace/server.rs`:
- Around line 1435-1473: These methods silently ignore a poisoned DB mutex by
returning on lock error; instead panic immediately so callers don't operate on
stale state. Replace the pattern "let Ok(...)= self.lock_db() else { return; }"
in db_set_module_info, db_remove_module, and db_unload_path with a clear
unwrap/expect from lock_db() (e.g. let mut db =
self.lock_db().expect("WorkspaceServer db lock poisoned") for the mutable case)
so the code fails fast on poison rather than silently no-op.

---

Outside diff comments:
In `@crates/biome_js_analyze/src/lint/correctness/no_unresolved_imports.rs`:
- Around line 137-145: The lint is calling
has_exported_symbol/find_js_exported_symbol for any ModuleInfo; add a guard to
only run export checks when target_info.kind is ModuleInfoKind::Js: after
obtaining target_info via ctx.module_info_for_path(resolved_path) (and before
constructing GetUnresolvedImportsOptions and before the has_exported_symbol
path), check target_info.kind == ModuleInfoKind::Js and skip export-resolution
logic (return Vec::new() or bypass has_exported_symbol) for non-JS kinds; ensure
both the wiring around target_info (where GetUnresolvedImportsOptions is
created) and the branch that calls has_exported_symbol/find_js_exported_symbol
(the code between the existing lines ~239–275) are updated to short-circuit for
non-JS ModuleInfoKind.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e2ff9908-42b9-40e0-a735-ea16aa1703d3

📥 Commits

Reviewing files that changed from the base of the PR and between 5b57d62 and 09f6163.

⛔ Files ignored due to path filters (3)
  • Cargo.lock is excluded by !**/*.lock and included by **
  • crates/biome_diagnostics_categories/src/categories.rs is excluded by !**/categories.rs and included by **
  • packages/@biomejs/backend-jsonrpc/src/workspace.ts is excluded by !**/backend-jsonrpc/src/workspace.ts and included by **
📒 Files selected for processing (64)
  • Cargo.toml
  • crates/biome_css_analyze/src/lib.rs
  • crates/biome_css_analyze/src/lint/nursery/no_unused_classes.rs
  • crates/biome_css_analyze/src/services/module_graph.rs
  • crates/biome_css_analyze/tests/spec_tests.rs
  • crates/biome_db/Cargo.toml
  • crates/biome_db/src/lib.rs
  • crates/biome_html_analyze/src/lib.rs
  • crates/biome_html_analyze/src/lint/nursery/no_undeclared_classes.rs
  • crates/biome_html_analyze/src/services/module_graph.rs
  • crates/biome_html_analyze/tests/spec_tests.rs
  • crates/biome_js_analyze/src/lib.rs
  • crates/biome_js_analyze/src/lint/correctness/no_private_imports.rs
  • crates/biome_js_analyze/src/lint/correctness/no_unresolved_imports.rs
  • crates/biome_js_analyze/src/lint/correctness/use_import_extensions.rs
  • crates/biome_js_analyze/src/lint/correctness/use_json_import_attributes.rs
  • crates/biome_js_analyze/src/lint/nursery/no_undeclared_classes.rs
  • crates/biome_js_analyze/src/lint/suspicious/no_deprecated_imports.rs
  • crates/biome_js_analyze/src/lint/suspicious/no_import_cycles.rs
  • crates/biome_js_analyze/src/services/database.rs
  • crates/biome_js_analyze/src/services/mod.rs
  • crates/biome_js_analyze/src/suppressions.tests.rs
  • crates/biome_js_analyze/tests/spec_tests.rs
  • crates/biome_js_type_info/src/type.rs
  • crates/biome_lsp/src/session.rs
  • crates/biome_module_graph/Cargo.toml
  • crates/biome_module_graph/README.md
  • crates/biome_module_graph/benches/module_graph.rs
  • crates/biome_module_graph/src/css_module_info/traverse.rs
  • crates/biome_module_graph/src/db/mod.rs
  • crates/biome_module_graph/src/db/project_database.rs
  • crates/biome_module_graph/src/db/queries.rs
  • crates/biome_module_graph/src/format_module_graph.rs
  • crates/biome_module_graph/src/js_module_info.rs
  • crates/biome_module_graph/src/js_module_info/module_resolver.rs
  • crates/biome_module_graph/src/lib.rs
  • crates/biome_module_graph/src/module_graph.rs
  • crates/biome_module_graph/src/module_graph/fs_proxy.rs
  • crates/biome_module_graph/src/path_info_cache.rs
  • crates/biome_module_graph/tests/snap/mod.rs
  • crates/biome_module_graph/tests/spec_tests.rs
  • crates/biome_resolver/Cargo.toml
  • crates/biome_resolver/src/db/inputs.rs
  • crates/biome_resolver/src/db/mod.rs
  • crates/biome_resolver/src/lib.rs
  • crates/biome_ruledoc_utils/Cargo.toml
  • crates/biome_ruledoc_utils/src/lib.rs
  • crates/biome_service/Cargo.toml
  • crates/biome_service/src/diagnostics.rs
  • crates/biome_service/src/file_handlers/css.rs
  • crates/biome_service/src/file_handlers/css/go_to.rs
  • crates/biome_service/src/file_handlers/graphql.rs
  • crates/biome_service/src/file_handlers/html.rs
  • crates/biome_service/src/file_handlers/html/go_to.rs
  • crates/biome_service/src/file_handlers/javascript.rs
  • crates/biome_service/src/file_handlers/javascript/go_to.rs
  • crates/biome_service/src/file_handlers/json.rs
  • crates/biome_service/src/file_handlers/mod.rs
  • crates/biome_service/src/workspace.rs
  • crates/biome_service/src/workspace/db.rs
  • crates/biome_service/src/workspace/server.rs
  • crates/biome_service/src/workspace/server.tests.rs
  • crates/biome_test_utils/Cargo.toml
  • crates/biome_test_utils/src/lib.rs

Comment thread crates/biome_module_graph/README.md
Comment thread crates/biome_module_graph/src/css_module_info/traverse.rs Outdated
Comment thread crates/biome_module_graph/src/db/queries.rs Outdated
Comment thread crates/biome_module_graph/src/db/queries.rs
Comment thread crates/biome_module_graph/src/path_info_cache.rs
Comment thread crates/biome_service/src/workspace/server.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/biome_css_analyze/src/lint/nursery/no_unused_classes.rs`:
- Around line 78-85: The new DB-backed lookup path using ctx.db(),
module_for_path(...), is_class_referenced_by_importers(...) and SymbolName built
from class_name.token_text_trimmed().text() needs corresponding spec fixtures:
add explicit valid and invalid test cases for the noUnusedClasses rule that
exercise importer-resolution (a class referenced only via an importer should be
marked valid) and the :global(...) exclusion (classes inside :global(...) should
be treated as used/valid). Create fixtures that construct SymbolName via the
same token text shape and include a negative case where a class is truly unused
to assert the rule flags it.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6200b86d-d673-486d-a02a-623878d7d672

📥 Commits

Reviewing files that changed from the base of the PR and between 19b3db1 and 7432687.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock and included by **
📒 Files selected for processing (5)
  • Cargo.toml
  • crates/biome_css_analyze/src/lib.rs
  • crates/biome_css_analyze/src/lint/nursery/no_unused_classes.rs
  • crates/biome_css_analyze/src/services/module_graph.rs
  • crates/biome_css_analyze/tests/spec_tests.rs

Comment thread crates/biome_css_analyze/src/lint/nursery/no_unused_classes.rs

@denbezrukov denbezrukov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🚀

Comment thread crates/biome_service/src/workspace/server.rs
Comment thread crates/biome_service/src/workspace/server.rs
Comment thread crates/biome_service/src/workspace/server.rs
@ematipico ematipico merged commit c463a15 into next May 24, 2026
37 of 39 checks passed
@ematipico ematipico deleted the feat/salsa-db branch May 24, 2026 08:26
@MichaReiser

Copy link
Copy Markdown
Contributor

The database inside the Workspace uses a Mutex. We need to lock it when we update it i.e. it's locked when we create a ModuleInfo instance, or we update an existing one.

I don't know enough about how Biome works today, but wrapping a Db in a Mutex isn't very common. The more common approach is to implement Clone on the Db (storage is cheap clonable), and creating clones whenever running some computation on another thread (e.g when going from main to background thread).

The only thing that's worth keeping in mind is that Salsa cancels all pending queries running on another thread when mutating an input, by panicking. You can use salsa::Cancelled to catch those panics at the Salsa/non-salsa boundary.

///
/// Tracked: depends on `js_module_info(db, module)` and on the CSS modules it
/// imports. If any of those change, this recomputes.
#[salsa::tracked(no_eq)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You probably want to use returns(ref) or returns(deref) here or salsa will clone the Vec every time this function is called (over returning a slice to the cached data).

Comment on lines +485 to +486
module: ModuleInfo,
symbol_name: SymbolName<'db>,

@MichaReiser MichaReiser Jun 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If ModuleInfo and SymbolName is a common combination, it might make sense to intern the data separately.

Technically, salsa only supports function with two arguments: db + one salsa struct. Functions with more than those two arguments are "lowered" into the two argument form by creating an ad-hoc interned struct that contains all argument values. Now, if you have 5 functions that take the same argument pairs, then Salsa interns those values 5 times. If you create one shared interned struct, then you only intern the value once

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Do you mean I should create a salsa::interned that contains both? ModuleInfo and the symbol?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes, but only if it's common that you call different queries with the same ModuleInfo and SymbolName.

(What salsa does internally is that it creates a salsa::interned fore each query that takes both ModuleInfo and SymbolName, but it's a different interned struct for each query, and, therefore, salsa ends up interning the same ModuleInfo/SymbolName multiple times, once for each query that's called with the same pair. Using your own struct prevents this

@ematipico

Copy link
Copy Markdown
Member Author

I don't know enough about how Biome works today, but wrapping a Db in a Mutex isn't very common. The more common approach is to implement Clone on the Db (storage is cheap clonable), and creating clones whenever running some computation on another thread (e.g when going from main to background thread).

Thank you for the suggestions @MichaReiser ! They are really appreciated. I am still finding the correct architecture and also learning how salsa works. The reason why the database is under a Mutex is that the Workspace itself implements Sync, which Salsa doesn't.

At the moment, the CLI sends the Workspace instance across threads (for each fine that is analysed); that's why there's a Mutex. I currently don't like it, because that Mutex is the current point of failure (bottleneck), so the only way to make the database lock-free would be to change how the CLI works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Diagnostic Area: diagnostocis A-Linter Area: linter A-LSP Area: language server protocol A-Project Area: project A-Resolver Area: resolver A-Type-Inference Area: type inference L-CSS Language: CSS and super languages L-HTML Language: HTML and super languages L-JavaScript Language: JavaScript and super languages L-JSON Language: JSON and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants