nextflow-io / nextflow-io/language-server

Workspace scan is deferred behind the debounce, so early cross-file requests see an almost-empty AST cache

Open
#175 1 comment 0 reactions 0 assignees View on GitHub

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: initializeinitializeddidChangeConfiguration (with a value that passes shouldInitialize) → wait for the "initialize" progress enddidOpen modules/greet/main.nftextDocument/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: 01 (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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.