laburnum 1.17.1

An LSP framework for building language servers and compilers, powered by an incremental query tree with content-addressed storage, task-based dataflow, and parallel queries.
Documentation
// Copyright Two Neutron Stars Incorporated and contributors
// SPDX-License-Identifier: BlueOak-1.0.0

//! Priority lane definitions and hierarchy.
//!
//! # Overview
//!
//! Lanes provide a way to assign priority to tasks in the Laburnum scheduler.
//! Each lane is represented as a single bit in a 32-bit integer, allowing
//! efficient bitwise operations for priority checking.
//!
//! # Lane Hierarchy (High to Low Priority)
//!
//! ## Sync Lanes (Highest Priority)
//!
//! - **SYNC_HYDRATION_LANE**: Hydration work that must complete synchronously
//! - **SYNC_LANE**: Blocking work (LSP requests, immediate user actions)
//!
//! These lanes should complete as fast as possible. Tasks on SYNC_LANE never
//! yield to other priorities.
//!
//! ## Input Lanes
//!
//! - **INPUT_CONTINUOUS_HYDRATION_LANE**: Hydration for input handling
//! - **INPUT_CONTINUOUS_LANE**: Continuous user input (hover, completion)
//!
//! Used for interactive features where low latency is critical for good UX.
//!
//! ## Default Lanes
//!
//! - **DEFAULT_HYDRATION_LANE**: Hydration for default priority work
//! - **DEFAULT_LANE**: Normal compilation work (parsing, type checking)
//!
//! The baseline priority for most compilation tasks.
//!
//! ## RPC Priority Lanes (4 lanes)
//!
//! - **RPC_LANE_0**: Highest priority RPC lane (oldest tasks)
//! - **RPC_LANE_1-2**: Middle priority RPC lanes
//! - **RPC_LANE_3**: Lowest priority RPC lane (new/yielded tasks)
//!
//! RPC tasks use a priority queue with aging. New tasks enter at RPC_LANE_3,
//! and existing tasks bubble up toward RPC_LANE_0 as new tasks arrive. Workers
//! steal from RPC_LANE_0 first, ensuring oldest tasks get priority.
//!
//! ## Async Lanes (12 lanes)
//!
//! - **ASYNC_HYDRATION_LANE**: Hydration for async work
//! - **ASYNC_LANE1-12**: Background compilation (codegen, optimization,
//!   analysis)
//!
//! Used for CPU-bound or IO-bound work that can be interrupted. Multiple async
//! lanes allow unrelated async work to progress independently without blocking
//! each other.
//!
//! ## Retry Lanes
//!
//! - **RETRY_LANE1-4**: Retry logic for operations that failed and need
//!   reattempt
//!
//! Dedicated lanes for retry logic to avoid interfering with new work.
//!
//! ## Idle Lanes (Low Priority)
//!
//! - **SELECTIVE_HYDRATION_LANE**: Selective hydration (React-specific concept)
//! - **IDLE_HYDRATION_LANE**: Hydration work when system is idle
//! - **IDLE_LANE**: Work to do when system has spare capacity
//!
//! Used for optimization and prefetching that improves future performance.
//!
//! ## Speculative Lane (Lowest Priority)
//!
//! - **SPECULATIVE_LANE**: Speculative precomputation, caching, warmup
//!
//! Work that might be useful later but isn't needed now. Only runs when
//! all other work is complete.
//!
//! # Design Notes
//!
//! ## Why Hydration Lanes?
//!
//! Hydration lanes come from React's architecture where server-rendered content
//! needs to be "hydrated" (made interactive) on the client. In a compiler
//! context, these could be used for restoring incremental compilation state or
//! loading cached results.
//!
//! ## Why Multiple Async Lanes?
//!
//! When work is IO-bound (waiting on file system, network), having multiple
//! lanes allows unrelated tasks to proceed independently. One slow file read
//! won't block an unrelated codegen task.
//!
//! ## Lane Selection Strategy
//!
//! - Use **SYNC_LANE** for work that blocks the user (LSP requests)
//! - Use **DEFAULT_LANE** for normal compilation pipeline
//! - Use **RPC_LANE_0-3** for RPC tasks (use `queue_rpc_task()` for priority)
//! - Use **ASYNC_LANE1-12** for background stages (distribute across lanes)
//! - Use **IDLE_LANE** for optimizations that improve future speed
//! - Use **SPECULATIVE_LANE** for precomputation that may never be needed

pub type Lane = u32;

pub const TOTAL_LANES: u8 = 31;

pub const LANE00: Lane = 0b0000000000000000000000000000000;
pub const LANE01: Lane = 0b0000000000000000000000000000001;
pub const LANE02: Lane = 0b0000000000000000000000000000010;
pub const LANE03: Lane = 0b0000000000000000000000000000100;
pub const LANE04: Lane = 0b0000000000000000000000000001000;
pub const LANE05: Lane = 0b0000000000000000000000000010000;
pub const LANE06: Lane = 0b0000000000000000000000000100000;
pub const LANE07: Lane = 0b0000000000000000000000001000000;
pub const LANE08: Lane = 0b0000000000000000000000010000000;
pub const LANE09: Lane = 0b0000000000000000000000100000000;
pub const LANE10: Lane = 0b0000000000000000000001000000000;
pub const LANE11: Lane = 0b0000000000000000000010000000000;
pub const LANE12: Lane = 0b0000000000000000000100000000000;
pub const LANE13: Lane = 0b0000000000000000001000000000000;
pub const LANE14: Lane = 0b0000000000000000010000000000000;
pub const LANE15: Lane = 0b0000000000000000100000000000000;
pub const LANE16: Lane = 0b0000000000000001000000000000000;
pub const LANE17: Lane = 0b0000000000000010000000000000000;
pub const LANE18: Lane = 0b0000000000000100000000000000000;
pub const LANE19: Lane = 0b0000000000001000000000000000000;
pub const LANE20: Lane = 0b0000000000010000000000000000000;
pub const LANE21: Lane = 0b0000000000100000000000000000000;
pub const LANE22: Lane = 0b0000000001000000000000000000000;
pub const LANE23: Lane = 0b0000000010000000000000000000000;
pub const LANE24: Lane = 0b0000000100000000000000000000000;
pub const LANE25: Lane = 0b0000001000000000000000000000000;
pub const LANE26: Lane = 0b0000010000000000000000000000000;
pub const LANE27: Lane = 0b0000100000000000000000000000000;
pub const LANE28: Lane = 0b0001000000000000000000000000000;
pub const LANE29: Lane = 0b0010000000000000000000000000000;
pub const LANE30: Lane = 0b0100000000000000000000000000000;
pub const LANE31: Lane = 0b1000000000000000000000000000000;

pub const ALL_LANES: Lane = 0b1111111111111111111111111111111;
pub const NO_LANE: Lane = LANE00;

pub const SYNC_HYDRATION_LANE: Lane = LANE01;
pub const SYNC_LANE: Lane = LANE02;
pub const SYNC_UPDATE_LANES: Lane = LANE02 | LANE04 | LANE06;

pub const INPUT_CONTINUOUS_HYDRATION_LANE: Lane = LANE03;
pub const INPUT_CONTINUOUS_LANE: Lane = LANE04;

pub const DEFAULT_HYDRATION_LANE: Lane = LANE05;
pub const DEFAULT_LANE: Lane = LANE06;

pub const ASYNC_HYDRATION_LANE: Lane = LANE07;

pub const RPC_LANE_0: Lane = LANE08;
pub const RPC_LANE_1: Lane = LANE09;
pub const RPC_LANE_2: Lane = LANE10;
pub const RPC_LANE_3: Lane = LANE11;
pub const RPC_LANES: Lane = RPC_LANE_0 | RPC_LANE_1 | RPC_LANE_2 | RPC_LANE_3;
pub const RPC_LANE_HIGH_IDX: usize = 7;
pub const RPC_LANE_LOW_IDX: usize = 10;

pub const ASYNC_LANES: Lane = LANE12
  | LANE13
  | LANE14
  | LANE15
  | LANE16
  | LANE17
  | LANE18
  | LANE19
  | LANE20
  | LANE21
  | LANE22
  | LANE23;
pub const ASYNC_LANE1: Lane = LANE12;
pub const ASYNC_LANE2: Lane = LANE13;
pub const ASYNC_LANE3: Lane = LANE14;
pub const ASYNC_LANE4: Lane = LANE15;
pub const ASYNC_LANE5: Lane = LANE16;
pub const ASYNC_LANE6: Lane = LANE17;
pub const ASYNC_LANE7: Lane = LANE18;
pub const ASYNC_LANE8: Lane = LANE19;
pub const ASYNC_LANE9: Lane = LANE20;
pub const ASYNC_LANE10: Lane = LANE21;
pub const ASYNC_LANE11: Lane = LANE22;
pub const ASYNC_LANE12: Lane = LANE23;

pub const RETRY_LANES: Lane = LANE24 | LANE25 | LANE26 | LANE27;
pub const RETRY_LANE1: Lane = LANE24;
pub const RETRY_LANE2: Lane = LANE25;
pub const RETRY_LANE3: Lane = LANE26;
pub const RETRY_LANE4: Lane = LANE27;
pub const SOME_RETRY_LANE: Lane = RETRY_LANE1;

pub const SELECTIVE_HYDRATION_LANE: Lane = LANE28;

pub const NON_IDLE_LANES: Lane = 0b0001111111111111111111111111111;
pub const IDLE_HYDRATION_LANE: Lane = LANE29;
pub const IDLE_LANE: Lane = LANE30;

pub const SPECULATIVE_LANE: Lane = LANE31;

pub fn lane_priority(lane: Lane) -> u8 {
  lane.trailing_zeros() as u8
}

pub fn is_rpc_lane(lane: Lane) -> bool {
  (lane & RPC_LANES) != 0
}

pub fn debug_lane(lanes: Lane) -> String {
  format!("{:#034b}", lanes)
}