nextflow-io / nextflow-io/language-server
Workspace scan is deferred behind the debounce, so early cross-file requests see an almost-empty AST cache
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 31
- Forks
- 8
- Avg merge
- 1d 10h
- Merged PRs (30d)
- 2
Description
The workspace scan is deferred behind the debounce, so early cross-file requests answer from an almost-empty AST cache.
What happens
On a fresh server, textDocument/references for a symbol that is referenced elsewhere returns [] for the first few seconds of a session, and workspace/symbol reports nothing (or an internal error). After a few seconds the same requests answer correctly, with no further client input.
Why
LanguageService.initialize() does not scan. It sets scanned = false, clears the AST cache and returns:
public void initialize(LanguageServerConfiguration configuration) {
synchronized (this) {
this.initialized = false;
this.scanned = false;
...
The scan happens in update0(), which runs on the 1s debounce — and only on a round where no file change is pending:
if( !scanned ) {
if( uris.isEmpty() ) {
uris = getWorkspaceFiles();
astCache.clear();
this.scanned = true;
}
else {
updateLater();
}
}
So the first didOpen of a session postpones the workspace scan by at least one more round: that round recompiles only the opened file and re-defers the scan. A client that opens a file and immediately asks for references — the normal opening move — gets an AST cache containing just that one file, and therefore an empty result.
initializeWorkspaces() wraps initialize() in the "initialize" progress notification, so a client that waits for progress.end() (the documented signal that the server is ready) is still too early: that notification covers only the cache clear, never the scan.
Reproduction
Workspace with a process defined in one file and used in another:
modules/greet/main.nf process GREET { ... }
main.nf include { GREET } from './modules/greet/main.nf'
workflow { GREET(names) }
Client sequence: initialize → initialized → didChangeConfiguration (with a value that passes shouldInitialize) → wait for the "initialize" progress end → didOpen modules/greet/main.nf → textDocument/references on GREET.
Result, polling the same request against one workspace (68 .nf files), with only the defining file ever opened:
after +0s: references=0
after +2s: references=0
after +5s: references=3 <- deferred scan finally ran
after +10s: references=3
workspace/symbol "" over the same window: 0 → 1 (the open file alone) → internal error while the AST cache is swapped → 86 once the scan lands.
I believe this is also what users report as diagnostics staying stale until they touch a file: the edit is what triggers an update round that eventually flushes the scan.
Suggestion
Either scan eagerly when the configuration change arrives (making initializeWorkspaces() actually initialize the workspace before progress.end()), or keep it lazy but let the pending scan win over a pending file change instead of being re-deferred by it, so it converges after one round rather than an unbounded number.
Failing that, a signal clients can wait on would be enough — which overlaps with #148.
For reference, the workaround on the client side (Serena) is to poll workspace/symbol until it reports symbols from more than one file before issuing any cross-file request.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating LanguageService.initialize(), update0(), and initializeWorkspaces(), then reproduce the initialize → initialized → didChangeConfiguration → didOpen → references sequence described here. Verify behavior with a workspace containing cross-file references and confirm that the initial scan completes before cross-file requests return incomplete results or that the pending scan converges after one update round.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100