11 KiB
Phase 3: Message Routing
Overview
Phase 3 focuses on implementing the message routing system, which is responsible for directing messages through the network hierarchy. This system must efficiently route messages based on priorities, optimize paths, and handle various routing scenarios. Building on the core framework and transport layer from previous phases, the message routing system forms a crucial part of the network's communication capabilities.
Key Components
1. MessageRouter Implementation (src/router/router.ts)
The MessageRouter class is responsible for determining how messages should travel through the network. It should:
- Allow registration of route handlers for specific message types
- Determine the appropriate routing strategy based on message properties
- Support various routing modes (upward, downward, hierarchical, etc.)
- Optimize paths for message delivery
Core Features
- Route Registration: Register handlers for specific message patterns
- Route Unregistration: Remove previously registered handlers
- Message Routing: Route messages based on recipient and routing config
- Path Calculation: Determine the optimal path for a message
Implementation Requirements
- Support pattern-based routing (exact matches, wildcards, regex)
- Support route prioritization
- Implement various routing strategies
- Provide default catch-all handler for unmatched messages
Edge Cases
- Handle undeliverable messages
- Prevent routing loops
- Handle timeouts for message routing
- Support message cancellation
2. PriorityMessageQueue Implementation (src/router/priority-queue.ts)
The PriorityMessageQueue manages message ordering based on priority. It should:
- Queue messages according to their priority level
- Process higher priority messages before lower priority ones
- Support batched processing for efficiency
- Implement rate limiting and backpressure mechanisms
Core Features
- Priority-Based Queueing: Insert messages in priority order
- Batch Processing: Process messages in batches for efficiency
- Rate Limiting: Control message processing rate
- Queue Management: Handle queue growth and cleanup
Implementation Requirements
- Support multiple priority levels
- Provide configurable batch sizes
- Implement pause/resume functionality
- Track queue statistics for monitoring
Edge Cases
- Handle queue overflow
- Prevent starvation of low-priority messages
- Manage memory usage for large queues
- Handle queue persistence during reconnection
3. MessageBatcher Implementation (src/router/message-batcher.ts)
The MessageBatcher groups related messages together for more efficient processing. It should:
- Batch messages of similar types
- Apply batching strategies based on message properties
- Flush batches based on triggers (time, size, priority)
- Support custom batching logic
Core Features
- Message Buffering: Group messages by type or other criteria
- Batch Flushing: Send batches based on triggers
- Buffer Management: Manage buffer sizes and timeouts
- Batch Optimization: Optimize batch sizes for network conditions
Implementation Requirements
- Support configurable batch sizes
- Implement various flushing strategies
- Provide manual and automatic flushing
- Track batch statistics
Edge Cases
- Handle partial batch delivery failures
- Manage priority within batches
- Handle timeouts for incomplete batches
- Support batch cancellation
Message Routing Strategies
1. Upward-Only Routing
Messages travel only up the hierarchy:
- Node → Parent → Parent's parent, etc.
- Useful for client-to-server communication
- Simplest routing strategy
2. Downward-Only Routing
Messages travel only down the hierarchy:
- Node → Children → Children's children, etc.
- Useful for server-to-client broadcasts
- Requires knowledge of the target's position in the hierarchy
3. Hierarchical Routing
Messages travel up, then down the hierarchy:
- Source → Parent → ... → Common ancestor → ... → Recipient
- Standard routing approach for most messages
- Requires finding the lowest common ancestor
4. Multi-Level Routing
Messages can take shortcuts through the hierarchy:
- May skip levels for efficiency
- Can use sibling connections to avoid going through parents
- More complex but more efficient for specific scenarios
5. Broadcast Routing
Messages are sent to multiple recipients:
- Can be targeted to specific levels or the entire network
- Uses a combination of other strategies for delivery
- Must handle duplicates and loops
Priority-Based Routing
The system should implement priority-based routing:
1. Critical Messages (Priority 0)
- Take the most direct path possible, potentially skipping levels
- Bypass queues where possible
- May use multiple redundant paths for reliability
2. High Priority Messages (Priority 1)
- Use optimized routing that may skip levels
- Processed before lower priority messages
- Delivered with high reliability guarantees
3. Medium Priority Messages (Priority 2)
- Use standard hierarchical routing
- May be delayed by higher priority messages
- Balance between efficiency and resource usage
4. Low Priority Messages (Priority 3)
- Use resource-efficient routing, even if slower
- May be batched aggressively
- Can be dropped during network congestion
Routing Configuration
The routing system should be highly configurable:
// Example configuration interface
interface MessageRoutingConfig {
routingMode: RoutingMode;
maxRoutingDistance: number;
priorityRoutingRules: {
[priority: number]: {
routingMode: RoutingMode;
maxRoutingDistance: number;
}
};
// Optional additional properties
timeToLive?: number; // Max hops before message expires
duplicateDetection?: boolean; // Enable duplicate detection
acknowledgement?: boolean; // Require acknowledgment
retryAttempts?: number; // Number of delivery attempts
retryDelay?: number; // Delay between retries
}
Implementation Details
Message Router
The MessageRouter should use pattern matching for route registration:
// Example patterns
router.registerRoute('chat.message', chatMessageHandler);
router.registerRoute('system.*', systemMessageHandler);
router.registerRoute(/^analytics\./, analyticsHandler);
The routing logic should:
- Find the appropriate handler for the message type
- Determine the routing strategy based on message priority
- Calculate the path to the recipient
- Forward the message along that path
Priority Queue
The PriorityMessageQueue should implement:
- Multiple internal queues, one per priority level
- A processing loop that always takes from the highest priority non-empty queue
- Batching to process multiple messages of the same priority
- Rate limiting to prevent overwhelming the network
Message Batcher
The MessageBatcher should:
- Group messages by type and/or recipient
- Apply configurable criteria for when to flush batches:
- Maximum batch size reached
- Maximum wait time elapsed
- High priority message forces a flush
- Manual flush triggered
- Optimize batch size based on network conditions
Testing Strategy
MessageRouter Tests
-
Route Registration Tests:
- Test exact match routing
- Test wildcard pattern routing
- Test regex pattern routing
- Test route priority
-
Routing Strategy Tests:
- Test upward routing
- Test downward routing
- Test hierarchical routing
- Test multi-level routing
- Test broadcast routing
-
Edge Case Tests:
- Test routing with missing recipients
- Test routing when path is blocked
- Test routing during network changes
- Test handling of undeliverable messages
PriorityMessageQueue Tests
-
Priority Ordering Tests:
- Test messages are processed in priority order
- Test same-priority messages are processed in FIFO order
- Test priority changes affect processing order
-
Batch Processing Tests:
- Test batch size configuration
- Test processing rate limits
- Test batch composition across priorities
-
Resource Management Tests:
- Test queue size limits
- Test memory usage patterns
- Test queue persistence during disconnection
MessageBatcher Tests
-
Batching Logic Tests:
- Test message grouping by type
- Test batch size limits
- Test time-based flushing
- Test priority-based flushing
-
Performance Tests:
- Test throughput with batching vs. without
- Test latency impact of batching
- Test optimization based on network conditions
-
Reliability Tests:
- Test handling batch delivery failures
- Test batch retries
- Test partial batch processing
Edge Cases and Considerations
1. Network Topology Changes
Consider how routing adapts to network changes:
- What happens to in-flight messages when topology changes?
- How are routing tables updated when nodes join/leave?
- How quickly do routing changes propagate?
2. Message Expiration
Implement time-to-live for messages:
- Messages should not circulate indefinitely
- Expired messages should be dropped with notifications
- TTL should be configurable per message type or priority
3. Routing Loops
Prevent messages from circulating indefinitely:
- Implement loop detection mechanisms
- Track message path history where needed
- Set maximum hop counts
4. Partial Network Failure
Handle partial network failures gracefully:
- Detect and route around failed nodes
- Queue messages for unreachable destinations
- Provide delivery status feedback
5. Backpressure
Implement backpressure mechanisms:
- Detect when downstream nodes are overwhelmed
- Slow down message production
- Prioritize essential messages during congestion
6. Large Messages
Handle large messages appropriately:
- Fragment large messages if needed
- Prioritize differently based on size
- Consider separate queues for large messages
Integration Points
The message routing system should integrate with:
- NetworkNode: Via the MessageRouter interface
- Transport Layer: For actual message delivery
- Plugin System: For custom routing strategies
- Monitoring: For performance metrics and debugging
Performance Optimization
Consider these optimizations:
- Route Caching: Cache frequently used routing paths
- Eager Path Calculation: Pre-calculate paths for known recipients
- Adaptive Batching: Adjust batch sizes based on network conditions
- Priority Tuning: Adjust priorities based on message patterns
Success Criteria
This phase is complete when:
- The MessageRouter correctly routes messages using all routing strategies
- The PriorityMessageQueue processes messages in the correct order
- The MessageBatcher efficiently groups and sends related messages
- All routing configurations work as expected
- Messages reach their destinations efficiently
- Edge cases are properly handled
- All tests pass with 100% code coverage
The message routing system is a critical component of the network library as it directly impacts the efficiency, reliability, and scalability of communication within the network. A well-implemented routing system will ensure messages flow optimally through the network even as it scales and evolves.