pub struct IndexCoordinator { /* private fields */ }Expand description
Coordinates index lifecycle, state transitions, and handler queries
The IndexCoordinator wraps WorkspaceIndex with explicit state management,
enabling LSP handlers to query the index readiness and implement appropriate
fallback behavior when the index is not fully ready.
§Architecture
LspServer
└── IndexCoordinator
├── state: Arc<RwLock<IndexState>>
├── index: Arc<WorkspaceIndex>
├── limits: IndexResourceLimits
├── caps: IndexPerformanceCaps
├── metrics: IndexMetrics
└── instrumentation: IndexInstrumentation§State Management
The coordinator manages three states:
Building: Initial scan or recovery in progressReady: Fully indexed and available for queriesDegraded: Available but with reduced functionality
§Performance Characteristics
- State checks are lock-free reads (cloned state, <100ns)
- State transitions use write locks (rare, <1μs)
- Query dispatch has zero overhead in Ready state
- Degradation detection is atomic (<10ns per check)
§Usage
use perl_parser::workspace_index::{IndexCoordinator, IndexState};
let coordinator = IndexCoordinator::new();
assert!(matches!(coordinator.state(), IndexState::Building { .. }));
// Transition to ready after indexing
coordinator.transition_to_ready(100, 5000);
assert!(matches!(coordinator.state(), IndexState::Ready { .. }));
// Query with degradation handling
let _result = coordinator.query(
|index| index.find_definition("my_function"), // full query
|_index| None // partial fallback
);Implementations§
Source§impl IndexCoordinator
impl IndexCoordinator
Sourcepub fn new() -> IndexCoordinator
pub fn new() -> IndexCoordinator
Create a new coordinator in Building state
Initializes the coordinator with default resource limits and an empty workspace index ready for initial scan.
§Returns
A coordinator initialized in IndexState::Building.
§Examples
use perl_parser::workspace_index::IndexCoordinator;
let coordinator = IndexCoordinator::new();Sourcepub fn with_limits(limits: IndexResourceLimits) -> IndexCoordinator
pub fn with_limits(limits: IndexResourceLimits) -> IndexCoordinator
Create a coordinator with custom resource limits
§Arguments
limits- Custom resource limits for this workspace
§Returns
A coordinator configured with the provided resource limits.
§Examples
use perl_parser::workspace_index::{IndexCoordinator, IndexResourceLimits};
let limits = IndexResourceLimits::default();
let coordinator = IndexCoordinator::with_limits(limits);Sourcepub fn with_limits_and_caps(
limits: IndexResourceLimits,
caps: IndexPerformanceCaps,
) -> IndexCoordinator
pub fn with_limits_and_caps( limits: IndexResourceLimits, caps: IndexPerformanceCaps, ) -> IndexCoordinator
Create a coordinator with custom limits and performance caps
§Arguments
limits- Resource limits for this workspacecaps- Performance caps for indexing budgets
Sourcepub fn state(&self) -> IndexState
pub fn state(&self) -> IndexState
Get current state (lock-free read via clone)
Returns a cloned copy of the current state for lock-free access in hot path LSP handlers.
§Returns
The current IndexState snapshot.
§Examples
use perl_parser::workspace_index::{IndexCoordinator, IndexState};
let coordinator = IndexCoordinator::new();
match coordinator.state() {
IndexState::Ready { .. } => {
// Full query path
}
_ => {
// Degraded/building fallback
}
}Sourcepub fn index(&self) -> &Arc<WorkspaceIndex>
pub fn index(&self) -> &Arc<WorkspaceIndex>
Get reference to the underlying workspace index
Provides direct access to the WorkspaceIndex for operations
that don’t require state checking (e.g., document store access).
§Returns
A shared reference to the underlying workspace index.
§Examples
use perl_parser::workspace_index::IndexCoordinator;
let coordinator = IndexCoordinator::new();
let _index = coordinator.index();Sourcepub fn limits(&self) -> &IndexResourceLimits
pub fn limits(&self) -> &IndexResourceLimits
Access the configured resource limits
Sourcepub fn performance_caps(&self) -> &IndexPerformanceCaps
pub fn performance_caps(&self) -> &IndexPerformanceCaps
Access the configured performance caps
Sourcepub fn instrumentation_snapshot(&self) -> IndexInstrumentationSnapshot
pub fn instrumentation_snapshot(&self) -> IndexInstrumentationSnapshot
Snapshot lifecycle instrumentation (durations, transitions, early exits)
Sourcepub fn notify_change(&self, _uri: &str)
pub fn notify_change(&self, _uri: &str)
Notify of file change (may trigger state transition)
Increments the pending parse count and may transition to degraded state if a parse storm is detected.
§Arguments
_uri- URI of the changed file (reserved for future use).
§Returns
Nothing. Updates coordinator metrics and state for the LSP workflow.
§Examples
use perl_parser::workspace_index::IndexCoordinator;
let coordinator = IndexCoordinator::new();
coordinator.notify_change("file:///example.pl");Sourcepub fn notify_parse_complete(&self, _uri: &str)
pub fn notify_parse_complete(&self, _uri: &str)
Notify parse completion for the Index/Analyze workflow stages.
Decrements the pending parse count, enforces resource limits, and may attempt recovery when parse storms clear.
§Arguments
_uri- URI of the parsed file (reserved for future use).
§Returns
Nothing. Updates coordinator metrics and state for the LSP workflow.
§Examples
use perl_parser::workspace_index::IndexCoordinator;
let coordinator = IndexCoordinator::new();
coordinator.notify_parse_complete("file:///example.pl");Sourcepub fn transition_to_ready(&self, file_count: usize, symbol_count: usize)
pub fn transition_to_ready(&self, file_count: usize, symbol_count: usize)
Transition to Ready state
Marks the index as fully ready for queries after successful workspace scan. Records the file count, symbol count, and completion timestamp. Enforces resource limits after transition.
§State Transition Guards
Only valid transitions:
Building→Ready(normal completion)Degraded→Ready(recovery after fix)
§Arguments
file_count- Total number of files indexedsymbol_count- Total number of symbols extracted
§Returns
Nothing. The coordinator state is updated in-place.
§Examples
use perl_parser::workspace_index::IndexCoordinator;
let coordinator = IndexCoordinator::new();
coordinator.transition_to_ready(100, 5000);Sourcepub fn transition_to_scanning(&self)
pub fn transition_to_scanning(&self)
Transition to Scanning phase (Idle → Scanning)
Resets build counters and marks the index as scanning workspace folders.
Sourcepub fn update_scan_progress(&self, total_count: usize)
pub fn update_scan_progress(&self, total_count: usize)
Update scanning progress with the latest discovered file count
Sourcepub fn transition_to_indexing(&self, total_count: usize)
pub fn transition_to_indexing(&self, total_count: usize)
Transition to Indexing phase (Scanning → Indexing)
Uses the discovered file count as the total index target.
Sourcepub fn transition_to_building(&self, total_count: usize)
pub fn transition_to_building(&self, total_count: usize)
Transition to Building state (Indexing phase)
Marks the index as indexing with a known total file count.
Sourcepub fn update_building_progress(&self, indexed_count: usize)
pub fn update_building_progress(&self, indexed_count: usize)
Update Building state progress for the Index/Analyze workflow stages.
Increments the indexed file count and checks for scan timeouts.
§Arguments
indexed_count- Number of files indexed so far.
§Returns
Nothing. Updates coordinator state and may transition to Degraded.
§Examples
use perl_parser::workspace_index::IndexCoordinator;
let coordinator = IndexCoordinator::new();
coordinator.transition_to_building(100);
coordinator.update_building_progress(1);Sourcepub fn transition_to_degraded(&self, reason: DegradationReason)
pub fn transition_to_degraded(&self, reason: DegradationReason)
Transition to Degraded state
Marks the index as degraded with the specified reason. Preserves the current symbol count (if available) to indicate partial functionality remains.
§Arguments
reason- Why the index degraded (ParseStorm, IoError, etc.)
§Returns
Nothing. The coordinator state is updated in-place.
§Examples
use perl_parser::workspace_index::{DegradationReason, IndexCoordinator, ResourceKind};
let coordinator = IndexCoordinator::new();
coordinator.transition_to_degraded(DegradationReason::ResourceLimit {
kind: ResourceKind::MaxFiles,
});Sourcepub fn check_limits(&self) -> Option<DegradationReason>
pub fn check_limits(&self) -> Option<DegradationReason>
Check resource limits and return degradation reason if exceeded
Examines current workspace index state against configured resource limits. Returns the first exceeded limit found, enabling targeted degradation.
§Returns
Some(DegradationReason)- Resource limit exceeded, contains specific limit typeNone- All limits within acceptable bounds
§Checked Limits
max_files: Total number of indexed filesmax_total_symbols: Aggregate symbol count across workspace
§Performance
- Lock-free read of index state (<100ns)
- Symbol counting is O(n) where n is number of files
Returns: Some(DegradationReason) when a limit is exceeded, otherwise None.
§Examples
use perl_parser::workspace_index::IndexCoordinator;
let coordinator = IndexCoordinator::new();
let _reason = coordinator.check_limits();Sourcepub fn enforce_limits(&self)
pub fn enforce_limits(&self)
Enforce resource limits and trigger degradation if exceeded
Checks current resource usage against configured limits and automatically transitions to Degraded state if any limit is exceeded. This method should be called after operations that modify index size (file additions, parse completions, etc.).
§State Transitions
Ready→Degraded(ResourceLimit)if limits exceededBuilding→Degraded(ResourceLimit)if limits exceeded
§Returns
Nothing. The coordinator state is updated in-place when limits are exceeded.
§Examples
use perl_parser::workspace_index::IndexCoordinator;
let coordinator = IndexCoordinator::new();
// ... index some files ...
coordinator.enforce_limits(); // Check and degrade if neededSourcepub fn record_early_exit(
&self,
reason: EarlyExitReason,
elapsed_ms: u64,
indexed_files: usize,
total_files: usize,
)
pub fn record_early_exit( &self, reason: EarlyExitReason, elapsed_ms: u64, indexed_files: usize, total_files: usize, )
Record an early-exit event for indexing instrumentation
Sourcepub fn query<T, F1, F2>(&self, full_query: F1, partial_query: F2) -> T
pub fn query<T, F1, F2>(&self, full_query: F1, partial_query: F2) -> T
Query with automatic degradation handling
Dispatches to full query if index is Ready, or partial query otherwise. This pattern enables LSP handlers to provide appropriate responses based on index state without explicit state checking.
§Type Parameters
T- Return type of the query functionsF1- Full query function type accepting&WorkspaceIndexand returningTF2- Partial query function type accepting&WorkspaceIndexand returningT
§Arguments
full_query- Function to execute when index is Readypartial_query- Function to execute when index is Building/Degraded
§Returns
The value returned by the selected query function.
§Examples
use perl_parser::workspace_index::IndexCoordinator;
let coordinator = IndexCoordinator::new();
let locations = coordinator.query(
|index| index.find_references("my_function"), // Full workspace search
|index| vec![] // Empty fallback
);