aboutsummaryrefslogtreecommitdiff
path: root/docs/dev
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-02-04 10:27:34 +0000
committerAleksey Kladov <[email protected]>2021-02-04 10:27:34 +0000
commit06aa34cd1038f69b708c32ed4e7a530170291a1b (patch)
tree9053a63f757bb827d35df83839d72b4b89b57432 /docs/dev
parent74a223faa33156be1b8b1a6880f9b63463027946 (diff)
More architecture.md
Diffstat (limited to 'docs/dev')
-rw-r--r--docs/dev/architecture.md44
1 files changed, 42 insertions, 2 deletions
diff --git a/docs/dev/architecture.md b/docs/dev/architecture.md
index 2ba8b7967..56ebaa3df 100644
--- a/docs/dev/architecture.md
+++ b/docs/dev/architecture.md
@@ -373,8 +373,48 @@ There's no additional checks in CI, formatting and tidy tests are run with `carg
373 373
374**Architecture Invariant:** tests do not depend on any kind of external resources, they are perfectly reproducible. 374**Architecture Invariant:** tests do not depend on any kind of external resources, they are perfectly reproducible.
375 375
376### Error Handling
377
378**Architecture Invariant:** core parts of rust-analyzer (`ide`/`hir`) don't interact with the outside world and thus can't fail.
379Only parts touching LSP are allowed to do IO.
380
381Internals of rust-analyzer need to deal with broken code, but this is not an error condition.
382rust-analyzer is robust: various analysis compute `(T, Vec<Error>)` rather than `Result<T, Error>`.
383
384rust-analyzer is a complex long-running process.
385It will always have bugs and panics.
386But a panic in an isolated feature should not bring down the whole process.
387Each LSP-request is protected by a `catch_unwind`.
388We use `always` and `never` macros instead of `assert` to gracefully recover from impossible conditions.
389
376### Observability 390### Observability
377 391
378I've run out of steam here :)
379rust-analyzer is a long-running process, so its important to understand what's going on inside. 392rust-analyzer is a long-running process, so its important to understand what's going on inside.
380We have hierarchical profiler (`RA_PROFILER=1`) and object counting (`RA_COUNT=1`). 393We have several instruments for that.
394
395The event loop that runs rust-analyzer is very explicit.
396Rather than spawning futures or scheduling callbacks (open), the event loop accepts an `enum` of possible events (closed).
397It's easy to see all the things that trigger rust-analyzer processing, together with their performance
398
399rust-analyzer includes a simple hierarchical profiler (`hprof`).
400It is enabled with `RA_PROFILE='*>50` env var (log all (`*`) actions which take more than `50` ms) and produces output like:
401
402```
40385ms - handle_completion
404 68ms - import_on_the_fly
405 67ms - import_assets::search_for_relative_paths
406 0ms - crate_def_map:wait (804 calls)
407 0ms - find_path (16 calls)
408 2ms - find_similar_imports (1 calls)
409 0ms - generic_params_query (334 calls)
410 59ms - trait_solve_query (186 calls)
411 0ms - Semantics::analyze_impl (1 calls)
412 1ms - render_resolution (8 calls)
413 0ms - Semantics::analyze_impl (5 calls)
414```
415
416This is cheap enough to enable in production.
417
418
419Similarly, we save live object counting (`RA_COUNT=1`).
420It is not cheap enough to enable in prod, and this is a bug which should be fixed.