Zettel — jDisc Stateless Searcher Chain Execution and Two-Phase Fill
In the stateless Java container (vespa/container-search/src/main/java/com/yahoo/search/searchchain/Execution.java), a search request traverses an immutable, dependency-ordered chain of Searcher components as a two-call protocol: search(Query, Execution) followed lazily by fill(Result, String summaryClass, Execution).
Mechanism & Upstream Grounding
- Per-Request
ExecutionCursor Over SharedSearcherInstances:Searchercomponents are singleton OSGi-managed graph nodes wired byvespa/container-disc; all per-request state lives inside theQuery,Result, andExecutionstack frame (INV-jdisc-stateless).
- Phase 1 —
Execution.search(Query)(Thin Hit Scatter-Gather):- Each
Searchermutates or inspects theQuery(YQL parsing, query profile resolution, embedding generation,federation) and delegates downstream viaexecution.search(query). - The terminal cluster dispatcher broadcasts the query to C++
protoncontent nodes, returning only global sort/relevance scores,GlobalId/LID handles, and optionalmatch-features— without fetching heavy document summary fields over the network.
- Each
- Phase 2 —
Execution.fill(Result, summaryClass)(On-Demand Summary Fetch):- Only after container-side merging,
global-phasereranking, and pagination (offset/hits) trim theResultto the final winning window doesexecution.fill(result)request docsum payloads from the content nodes that own the winning hits.
- Only after container-side merging,
Boundary Conditions & Trade-offs
- Early Fill Anti-Pattern: Calling
execution.fill(result)inside a customSearcherbefore top-K trimming forcesprotonnodes to decompress and serialize full document summaries for all intermediate scatter-gather candidates, multiplying network and disk I/O (see inv-jdisc-searcher-stateless-fill-discipline and querying-yql).