mirror of https://github.com/astral-sh/ruff
High-level project overview and contributing guide for `ruff server` (#10565)
## Summary This PR adds an overview and roadmap to the `README.md` for the `ruff_server` crate along with a rudimentary `CONTRIBUTING.md` that explains some of the technical decisions behind the project and basic information about local testing.
This commit is contained in:
parent
a28776e3aa
commit
825fd7c990
|
|
@ -0,0 +1,32 @@
|
|||
## Contributing to the Ruff Language Server
|
||||
|
||||
This is a mostly free-form guide with resources to help you get started with contributing to `ruff server`.
|
||||
|
||||
### Project Architecture
|
||||
|
||||
`ruff_server` uses a [lock-free data model](https://github.com/astral-sh/ruff/blob/a28776e3aa76c18dcc1f1ad36a48aa189040860d/crates/ruff_server/src/session.rs#L17-L26) to represent its state. The server runs in a [continuous event loop](https://github.com/astral-sh/ruff/blob/a28776e3aa76c18dcc1f1ad36a48aa189040860d/crates/ruff_server/src/server.rs#L146-L173) by listening to incoming messages
|
||||
over `stdin` and dispatches [tasks](https://github.com/astral-sh/ruff/blob/a28776e3aa76c18dcc1f1ad36a48aa189040860d/crates/ruff_server/src/server/schedule/task.rs#L29-L40) based on the type of message. A 'task' can either be 'local' or 'background' - the former kind has
|
||||
exclusive mutable access to the state and execute immediately, blocking the event loop until their completion. The latter kind, background
|
||||
tasks, run immediately on a thread pool with an immutable snapshot of the state, and do _not_ block the event loop unless the thread pool
|
||||
queue is full, in which case the server will block on available queue space.
|
||||
|
||||
[Snapshots of the server state](https://github.com/astral-sh/ruff/blob/a28776e3aa76c18dcc1f1ad36a48aa189040860d/crates/ruff_server/src/session.rs#L28-L35) use atomic reference-counted pointers (`Arc`) to prevent unnecessary cloning of large text files. If the contents
|
||||
of the text file need to be updated, the state will create a new `Arc` to store it. This allows a local task to run at the same time as multiple background tasks
|
||||
without changing the state the background tasks are working with. This only applies to background tasks started _before_ the local task though, as a local task blocks
|
||||
the handling of further messages (and therefore, dispatching future tasks) until its completion.
|
||||
|
||||
`ruff_server` uses the `lsp-server` and `lsp-types` crates in favor of a more involved framework like `tower-lsp` because of the flexibility that the former gives us
|
||||
in our implementation. A goal for this project was to take an architectural approach similar to `rust-analyzer`, with locally running tasks that access the state exclusively,
|
||||
along with background tasks that reference a snapshot of the state. `tower-lsp` would have given us less control over execution order, which may have required us to use locks
|
||||
or other thread synchronization methods to ensure data integrity. In fact, the `tower-lsp` scheduler has [existing issues](https://github.com/ebkalderon/tower-lsp/issues/284) around
|
||||
data races and out-of-order handler execution. Our approach avoids this issue by dis-allowing `async` in tasks and using a scheduler focused on data mutability and access.
|
||||
|
||||
### Testing
|
||||
|
||||
Most editors with LSP support (VS Code is a notable exception) can work with a language server by providing a server command in their respective configurations. Guides for configuring specific editors to use Ruff will be available soon.
|
||||
|
||||
If you want to test any changes you've made to `ruff server`, you can simply modify the editor configuration to use your debug binary. Unless you've already installed this debug build in your `PATH` (in which case you can just keep using `ruff server --preview` as the server command) the server command should be the path to your locally-built ruff executable (usually `<path to your ruff source>/target/debug/ruff`) along with the arguments `server` and `--preview`. Make sure to (re)build the server with `cargo build -p ruff`!
|
||||
|
||||
#### Testing In VS Code
|
||||
|
||||
At the moment, the [pre-release version](https://github.com/astral-sh/ruff-vscode/tree/pre-release) of Ruff's new VS Code extension only has the option to use the bundled Ruff binary. Configuration to use a custom Ruff executable path will be ready soon.
|
||||
|
|
@ -1 +1,10 @@
|
|||
## The Ruff Language Server
|
||||
|
||||
Welcome! `ruff server` is a language server that powers editor integrations with Ruff. The job of the language server is to
|
||||
listen for requests from the client, (in this case, the code editor of your choice) and call into Ruff's linter and formatter
|
||||
crates to create real-time diagnostics or formatted code, which is then sent back to the client. It also tracks configuration
|
||||
files in your editor's workspace, and will refresh its in-memory configuration whenever those files are modified.
|
||||
|
||||
### Contributing
|
||||
|
||||
If you're interested in contributing to `ruff server` - well, first of all, thank you! Second of all, you might find the [**contribution guide**](CONTRIBUTING.md) to be a useful resource. Finally, don't hesitate to reach out on our [**Discord**](https://discord.com/invite/astral-sh) if you have questions.
|
||||
|
|
|
|||
Loading…
Reference in New Issue