Server Services and Routines
This page explains the internal services, routines, and background processes that run inside the hlquery server.
Architecture Overview
hlquery is built on an event-driven architecture with the following core components:
- HTTP Server: Handles incoming HTTP requests
- Socket Engine: Manages network I/O using epoll/poll
- RocksDB Storage Engine: Provides persistent storage using RocksDB
- Search API: Processes search queries and document operations
- Thread Pool Manager: Manages worker threads for concurrent processing
- Timer Manager: Handles periodic tasks and scheduled operations
- Log Manager: Centralized logging system
Main Event Loop
The server's main event loop (hlquery::Run()) orchestrates all system operations:
Loop Structure
while (true) {
// 1. Check shutdown flags
if (force_exit || shutting_down) break;
// 2. Periodic database flush (once per second)
if (now != oldtime) {
Database->Flush();
}
// 3. Network event processing
SocketEngine::DispatchEvents();
// 4. Pending write processing
SocketEngine::DispatchTrialWrites();
// 5. Deferred action processing
ActionList::ProcessActions();
// 6. Lazy operations
DaemonHandler::ProcessLazyOperations();
// 7. Timer processing
Timers->Tick();
// 8. Socket engine optimization
DaemonHandler::ProcessSocketEngineOptimization();
}
Core Routines
1. Network Event Processing
Function: SocketEngine::DispatchEvents()
Processes all pending I/O events from the socket engine (epoll/poll). This handles:
- Incoming HTTP requests
- Connection management
- Network I/O operations
- Client disconnections
Frequency: Every event loop iteration
Performance: Uses adaptive timeout based on pending work:
- Non-blocking (timeout=0) when pending work exists
- Blocking (timeout=-1) when idle for maximum efficiency
2. Pending Write Processing
Function: SocketEngine::DispatchTrialWrites()
Attempts immediate writes for sockets that are ready, reducing latency for response delivery.
Frequency: Every event loop iteration
Purpose: Optimize response delivery by writing data as soon as sockets are writable
3. Deferred Action Processing
Function: ActionList::ProcessActions()
Executes queued operations that were deferred to avoid blocking the event loop. This includes:
- Expensive database operations
- Background indexing tasks
- Metadata updates
Frequency: Every event loop iteration
Purpose: Prevent blocking operations from affecting request latency
4. Lazy Operations
Function: DaemonHandler::ProcessLazyOperations()
Handles expensive operations that can be processed incrementally during idle periods:
- Background compaction
- Index optimization
- Cache warming
- Statistics collection
Frequency: Every event loop iteration (with internal throttling)
Purpose: Utilize idle CPU cycles for maintenance tasks
5. Timer Processing
Function: Timers->Tick()
Executes scheduled periodic tasks:
- Database flushes
- Health checks
- Statistics collection
- Cache cleanup
- Connection timeout handling
Frequency: Every event loop iteration (timers fire based on their schedule)
Purpose: Handle time-based operations and scheduled maintenance
6. Socket Engine Optimization
Function: DaemonHandler::ProcessSocketEngineOptimization()
Adjusts system behavior based on load:
- Adaptive sleep intervals
- Throughput optimization
- Connection pool sizing
- I/O buffer tuning
Frequency: Every event loop iteration
Purpose: Optimize performance based on current system load
7. Database Flush
Function: Database->Flush()
Periodically flushes in-memory data to disk for durability.
Frequency: Once per second (when system time changes)
Purpose: Ensure data durability and prevent data loss
HTTP Server Services
Request Processing Pipeline
- Connection Acceptance: New connections are accepted by the HTTP server
- Request Parsing: HTTP requests are parsed into
HttpRequeststructures - Route Resolution: Routes are resolved using
ResolveHttpRoute()function - Authentication: API key validation (if enabled)
- Handler Execution: Appropriate handler function is called
- Response Generation:
HttpResponseis generated - Response Sending: Response is sent back to client
Route Handlers
All route handlers are implemented in the SearchAPI class:
Collection Management
HandleCreateCollection()- Create new collectionsHandleDeleteCollection()- Delete collectionsHandleListCollections()- List all collectionsHandleGetCollection()- Get collection detailsHandleUpdateCollection()- Update collection schema
Document Management
HandleAddDocument()- Add documentsHandleUpdateDocument()- Update documentsHandleDeleteDocument()- Delete documentsHandleGetDocument()- Retrieve documentsHandleListDocuments()- List documents in collectionHandleBulkImportDocuments()- Bulk import documentsHandleDeleteDocumentsByFilter()- Delete documents by filter
Search Operations
HandleSearch()- Full-text searchHandleVectorSearch()- Vector similarity searchHandleMultiSearch()- Multi-collection searchHandleFacetCounts()- Faceted searchHandleExportDocuments()- Document exportHandleAutocomplete()- Autocomplete suggestions (planned)HandleSpellcheck()- Spell checking (planned)HandleAnalyticsClick()- Click analytics (planned)
Configuration Management
HandleListSynonyms()- List synonyms in collectionHandleListAllSynonyms()- List all synonyms (global endpoint)HandleCreateOrUpdateSynonym()- Manage synonymsHandleGetSynonym()- Get synonym detailsHandleDeleteSynonym()- Delete synonymsHandleListStopwords()- List stopwords in collectionHandleListAllStopwords()- List all stopwords (global endpoint)HandleCreateStopword()- Add stopwordsHandleDeleteStopword()- Delete stopwordsHandleListOverrides()- List search overridesHandleCreateOrUpdateOverride()- Manage overridesHandleGetOverride()- Get override detailsHandleDeleteOverride()- Delete overridesHandleListAliases()- List aliasesHandleCreateOrUpdateAlias()- Manage aliasesHandleGetAlias()- Get alias detailsHandleDeleteAlias()- Delete aliases
System Endpoints
HandleHealth()- Health checkHandleStatus()- Detailed statusHandleStats()- Server statisticsHandleMetrics()- JSON metrics (currently minimal)HandleConnections()- Connection countHandleRocksDB()- RocksDB engine statsHandleDocTotal()- Document countsHandleUpdateCounters()- Update counters
Thread Pool Services
Thread Pool Manager
Class: hlquery_threadpool::ThreadPoolManager
Manages multiple specialized thread pools:
HTTP Thread Pool
- Handles HTTP request processing
- Processes search queries
- Manages document operations
Database Thread Pool
- Handles database I/O operations
- Processes RocksDB compaction
Search Thread Pool
- Processes search queries
- Handles indexing operations
- Manages vector operations
Tuning tip: If searches feel slow even when CPU is idle, confirm the target collection is fully indexed, store RocksDB on fast NVMe/SSD with a generous block cache, and raise search_pool_threads (30+ threads) inside the <performance …> block in run/conf/hlquery.conf. This prioritizes the search pool and gives worker threads enough room to service bursts without waiting on HTTP/write pools.
Thread Pool Lifecycle
- Initialization: Thread pools are created after fork (if daemon mode)
- Worker Threads: Each pool spawns worker threads
- Task Queue: Tasks are queued and distributed to workers
- Shutdown: Graceful shutdown waits for tasks to complete
RocksDB database Services
DBManager
Class: DBManager
Provides persistent key-value storage using RocksDB's RocksDB architecture:
Core Operations
- Put: Write key-value pairs
- Get: Read values by key
- Delete: Remove keys
- Flush: Persist in-memory data to disk
Background Services
- Compaction: Merges SSTables to optimize storage
- Block Cache: Caches frequently accessed data blocks
- Index Cache: Caches index and filter blocks
- Write-Ahead Log (WAL): Ensures durability
Storage Components
Memtable
- In-memory write buffer
- Sorted by key
- Flushed to disk when full
SSTables (Sorted String Tables)
- Immutable on-disk data files
- Organized in levels
- Merged during compaction
Block Cache
- LRU cache for data blocks
- Reduces disk I/O
- Configurable size
Search Services
SearchAPI
Class: SearchAPI
Singleton service that handles all search-related operations:
Search Processing
- Query Parsing: Parses search parameters
- Collection Lookup: Validates collection exists
- Index Search: Searches inverted index
- Result Ranking: Scores and ranks results
- Filtering: Applies filters
- Sorting: Sorts results
- Pagination: Paginates results
- Highlighting: Highlights matching terms
Vector Search
- Embedding generation
- Vector similarity calculation
- Hybrid search (lexical + vector)
HybridStorageManager
Class: hlquery_storage::HybridStorageManager
Manages document storage and indexing:
Services
- Document Storage: Stores documents in collections
- Index Management: Maintains inverted indexes
- Metadata Management: Tracks collection metadata
- Counter Management: Maintains document counts
Logging Services
LogManager
Class: LogManager
Centralized logging system with multiple log targets:
Log Targets
- Console output
- File logging
- Syslog integration
- Custom handlers
Log Levels
- Critical: System-critical errors
- Error: Error conditions
- Warning: Warning messages
- Normal: Normal operations
- Debug: Debug information
Timer Services
TimerManager
Class: TimerManager
Manages periodic and scheduled tasks:
Timer Types
- One-shot: Fire once after delay
- Periodic: Fire at regular intervals
- Scheduled: Fire at specific times
Common Timers
- Database flush timer (1 second)
- Health check timer (30 seconds)
- Statistics collection timer (60 seconds)
- Cache cleanup timer (5 minutes)
Initialization Sequence
The server initializes in the following order:
- Configuration Loading: Load and parse configuration files
- Log Manager: Initialize logging system
- Timer Manager: Create timer system
- Database Engine: Initialize RocksDB database
- Search API: Initialize search services
- User Auth: Initialize authentication (if enabled)
- Thread Pools: Initialize thread pools (after fork)
- HTTP Server: Start HTTP server
- Metadata Scan: Scan and load collection metadata
- Ready State: Mark server as ready to accept requests
Shutdown Sequence
Graceful shutdown follows this sequence:
- Shutdown Signal: Receive shutdown signal
- Stop Accepting: Stop accepting new connections
- Complete Requests: Wait for in-flight requests to complete
- Flush Database: Flush all pending writes
- Close Connections: Close all client connections
- Shutdown Thread Pools: Stop thread pools gracefully
- Cleanup Resources: Release all resources
- Exit: Terminate process
Performance Optimizations
Adaptive Behavior
The server implements adaptive behavior patterns:
- Adaptive Timeouts: Socket timeouts adjust based on load
- Lazy Processing: Expensive operations deferred to idle periods
- Connection Pooling: Reuses connections for efficiency
- Batch Processing: Groups operations for efficiency
- Cache Warming: Preloads frequently accessed data
Resource Management
- Memory Pools: Reduces allocation overhead
- Lock-Free Structures: Minimizes contention
- Zero-Copy I/O: Reduces data copying
- Efficient Data Structures: Optimized for common operations
Monitoring and Observability
Metrics Collection
The server collects various metrics:
- Request counts and latencies
- Cache hit/miss rates
- Connection counts
- Memory usage
- Disk I/O statistics
- Search performance
Health Checks
Multiple health check mechanisms:
/healthendpoint for basic health/statusendpoint for detailed status- Internal health monitoring
- Automatic recovery from transient failures
Error Handling
Error Recovery
The server implements robust error handling:
- Graceful Degradation: Continues operating with reduced functionality
- Automatic Retry: Retries failed operations
- Circuit Breakers: Prevents cascading failures
- Resource Limits: Prevents resource exhaustion
Logging and Diagnostics
All errors are logged with context:
- Error type and message
- Stack traces (in debug mode)
- Request context
- System state
Research & Future Work
- Daemon Resiliency & Observability: We are instrumenting the daemon with structured health telemetry, per-stage query timings, and automatic restart safeguards so background deployments recover faster.
- TTC Instrumentation: Time-to-Consistency (TTC) metrics will tie RocksDB compaction scheduling to write visibility, giving operators visibility into how soon a write becomes search-visible while keeping throughput sane.
- Hybrid Filtering & Tiered Storage: Future work will add selectivity-aware filtering planners and cold-tier offload for vector shards, which will require coordination between the search services documented here and the new dispatcher/routing layers.
For implementation notes and experiments, see etc/research/2026-02-26.md in the repo.