How to optimize or defer project-wide document invalidation to prevent update timeouts during update() method execution? #1925
Replies: 1 comment
-
Hey @we-wake-act21,
Large changes simply need more time to update the workspace state. This is kind of expected. Having a static timeout will always lead to issues somehow (i.e. multiple file changes at the same time on large workspaces). I would think you could dynamically adjust the timeout length based on the type of change (i.e. config change vs document change).
Maybe? But I wouldn't go down that route, see below for better recommendations.
Since the document in question usually relies on other files in the workspace to successfully go through the lifecycle stages (especially linking, which usually requires all other documents to have arrived at the
Yes, definitely. And this is likely where you would be able to get most of your performance benefits. Calling
In case the project config neither changes how you parse your code nor how elements are being exported, you can simply adjust the
Ideally, you would create a delta of the previous config vs the new config and perform less intrusive changes in case the delta doesn't affect the documents. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Context
I'm working on a language server implementation that uses a custom
ProjectManager
and a modifiedscope-provider
. I have anupdate<T>
method that handles document updates and uses a timeout mechanism to reject any update that takes more than 5000ms.You can find the full
update
method here:🔗
[ModelService.update](https://github.com/CrossBreezeNL/crossmodel/blob/ee40293212688b2eca96820dc68b0bc44ce63b34/extensions/crossmodel-lang/src/model-server/model-service.ts#L134)
In some scenarios—especially when editing a file like
Project.json
—this timeout is triggered even though the update would eventually succeed if given more time.Root Cause Analysis
After some profiling, I narrowed the cause down to two main contributors:
Initially contained inefficient recursive logic, which has since been optimized. This resolved a portion of the slowness.
Currently designed to invalidate all documents associated with a project when certain project files (like
Project.json
) are updated. This leads to a flood of rebuilds.Here's a simplified version of the
ProjectManager
logic responsible for this:This is invoked during
documentManager.onUpdate()
and has a major impact when a project file is edited, especially with ~108 files involved.Problem
Since the invalidation and rebuilds are synchronous and aggressive, it frequently causes the
update()
method (linked above) to exceed its 5000ms timeout window, especially under large project loads.My Questions
update()
?onBuildUpdate
to make it more incremental, lazy, or event-driven rather than invalidating all documents upfront?Additional Notes
Project.json
results in all 100+ documents being rebuilt, which is not ideal for responsiveness.Any advice or examples from similar setups (Langium or otherwise) would be greatly appreciated. Thanks in advance!
Beta Was this translation helpful? Give feedback.
All reactions