@@ -9,20 +9,18 @@ This is a design note on the FSharpChecker component and its operations queue.
99FSharpChecker maintains an operations queue. Items from the FSharpChecker operations queue are processed
1010sequentially and in order.
1111
12- In addition to operations in the queue, there is also a low-priority, interleaved background operation
13- to bring the checking of the checking of "the current background project" up-to-date. When the queue is empty
14- this operation is run in small incremental fragments of work. This work id cooperatively time-sliced to be approximately <50ms,
15- (see `maxTimeShareMilliseconds` in IncrementalBuild.fs).
16-
17- The For a working definition of "current background project"
18- you currently have to see the calls to `StartBackgroundCompile`
19- in [service.fs](https://github.com/fsharp/FSharp.Compiler.Service/blob/master/src/fsharp/vs/service.fs),
20- where an API call which in turn calls StartBackgroundCompile indicates that the current background project has been specified.
21-
22- Many calls to the FSharpChecker API enqueue an operation in the FSharpChecker compiler queue. These correspond to the
12+ The thread processing these requests can also run a low-priority, interleaved background operation when the
13+ queue is empty. This can be used to implicitly bring the background check of a project "up-to-date".
14+ When the operations queue is empty this background work is run in small incremental fragments.
15+ This work is cooperatively time-sliced to be approximately <50ms, (see `maxTimeShareMilliseconds` in
16+ IncrementalBuild.fs). The project to be checked in the background is set implicitly
17+ by calls to ``CheckFileInProject`` and ``ParseAndCheckFileInProject``.
18+ To disable implicit background checking completely, set ``checker.ImplicitlyStartBackgroundWork`` to false.
19+
20+ Most calls to the FSharpChecker API enqueue an operation in the FSharpChecker compiler queue. These correspond to the
2321calls to EnqueueAndAwaitOpAsync in [service.fs](https://github.com/fsharp/FSharp.Compiler.Service/blob/master/src/fsharp/vs/service.fs).
2422
25- * For example, calling `ParseAndCheckProject` enqueues a `ParseAndCheckProjectImpl` operation. The length of the
23+ * For example, calling `ParseAndCheckProject` enqueues a `ParseAndCheckProjectImpl` operation. The time taken for the
2624 operation will depend on how much work is required to bring the project analysis up-to-date.
2725
2826* Likewise, calling any of `GetUsesOfSymbol`, `GetAllUsesOfAllSymbols`, `ParseFileInProject`,
@@ -32,30 +30,25 @@ calls to EnqueueAndAwaitOpAsync in [service.fs](https://github.com/fsharp/FSharp
3230 vary - many will be very fast - but they won't be processed until other operations already in the queue are complete.
3331
3432Some operations do not enqueue anything on the FSharpChecker operations queue - notably any accesses to the Symbol APIs.
35- These are multi-threaded access to the TAST data produced by other FSharpChecker operations.
36-
37- In advanced interactive scenarios you may need to consider contributing design changes and extensions to how the FSharpChecker queue works,
38- in order to better serve your needs. Some tools throw a lot of interactive work at the FSharpChecker operations queue.
39- If you are writing such a component, we encourage you to get more involved in making carefully considered
40- changes, cleanup and documentation to how the queue works, to ensure it is suitable for your needs.
41-
42- For example, from the FCS point of view, it is plausible to consider changing of extending how the
43- FSharpChecker operations queue works - the design of the queue and its processing is not sacred.
44- In theory you could submit extensions and documentation that allow prioritization of operations, or interleaving of
45- operations, or cancellation of operations, or more explicitness about the "current background project", and so on.
46-
47- Finally, for those writing interactive editors which use FCS, in the current state of affairs you
48- should be cautious about having any auto-operation (e.g. operations like "Find Unused Declarations"
49- which run automatically and are unassociated with a user action, but not operations like "Find All References"
50- which a user explicitly triggers) request a check of the entire project. That will cause very long operations
51- and contention on the FSharpChecker operations queue. Any such very-long-running request should normally be associated
52- with a user action, and preferably it should be cancellable.
53-
54- Alternatively, it is reasonable to trigger these
55- kinds of auto-operations when the ProjectChecked event is triggered on FSharpChecker. This event indicates the
56- completion of interleaved checking of the "current background project" (specified above). Again, if
57- the spec of "current background project" is not suitable or sufficiently controlled for your needs, please
58- help to document it and adjust it.
33+ These use cross-threaded access to the TAST data produced by other FSharpChecker operations.
34+
35+ Some tools throw a lot of interactive work at the FSharpChecker operations queue.
36+ If you are writing such a component, consider running your project against a debug build
37+ of FSharp.Compiler.Service.dll to see the Debug.WriteLine messages indicating the length of the
38+ operations queuea and the time to process requests.
39+
40+ For those writing interactive editors which use FCS, you
41+ should be cautious about operations that request a check of the entire project.
42+ For example, be careful about requesting the check of an entire project
43+ on operations like "Highlight Symbol" or "Find Unused Declarations"
44+ (which run automatically when the user opens a file or moves the cursor).
45+ as opposed to operations like "Find All References" (which a user explicitly triggers).
46+ Project checking can cause long and contention on the FSharpChecker operations queue.
47+
48+ Requests to FCS can be cancelled by cancelling the async operation. (Some requests also
49+ include additional callbacks which can be used to indicate a cancellation condition).
50+ This cancellation will be effective if the cancellation is performed before the operation
51+ is executed in the operations queue.
5952
6053Summary
6154-------
0 commit comments