๐ Technical Design 010 โ DI Bootstrapping & Early Initialization¶
| Field | Value |
|---|---|
| ID | TD-010 |
| Title | DI Bootstrapping & Early Initialization |
| Status | Completed |
| Owner | Contributors |
| Audience | Contributors, maintainers, DI system users |
| Created | 2025-10-02 |
| Last Updated | 2025-10-03 |
| Reviewers | TBD |
| Approvers | TBD |
| Tracking | Phase 2 of DI Roadmap |
| Related | 001-dependency-injection-roadmap.md |
๐งญ 1. Summary¶
This technical design implements Phase 2 of the DI roadmap by adding automatic bootstrapping with early initialization support to the DiContainer. The design introduces dependency cycle detection, fail-fast validation, and thread-safe singleton resolution during the bootstrap process.
At a glance:
- Automatic bootstrapping triggered on first resolve call
- Manual bootstrap capability with
container.bootstrap() - Dependency cycle detection with clear error reporting
- Early singleton resolution and validation
- Thread-safe bootstrapping process with idempotent behavior
๐ 2. Context and Problem Statement¶
The Phase 1 container provides registration and resolution but lacks initialization orchestration and dependency validation:
Current Limitations¶
- No Dependency Validation - Circular dependencies discovered at runtime during resolution
- Late Error Detection - Dependency issues only surface when specific services are resolved
- No Initialization Control - No way to eagerly initialize critical singletons
- Missing Validation - No pre-runtime validation of dependency graph integrity
2.1 Goals¶
- Automatic Bootstrapping - Trigger bootstrap process on first resolve call
- Dependency Cycle Detection - Identify and report circular dependencies before runtime
- Early Singleton Resolution - Resolve all registered singletons during bootstrap
- Fail-Fast Validation - Validate dependency graph integrity at bootstrap time
- Thread-Safe Operations - Ensure bootstrap process is thread-safe and idempotent
2.2 Non-Goals (Out of Scope)¶
- Named registrations or qualifiers (future consideration)
- Advanced lifecycle scopes beyond singleton/transient (Phase 4+)
- Configuration binding and property injection (Phase 4)
- Module scanning and auto-discovery (Phase 5)
2.3 Assumptions and Constraints¶
- Phase 1 DiContainer implementation is complete and available
- Dependency tracking infrastructure from Phase 1 is functional
- Bootstrap process should be optional and manual override-able
- Thread safety without significant performance degradation
๐งฉ 3. Design Overview¶
The bootstrap system transforms the Phase 1 container into a self-validating, dependency-aware container with automatic initialization orchestration. The design centers around atomic operations, container status management, and * *graph-based dependency analysis**.
3.1 Core Design Principles¶
๐ Container Status Lifecycle: Three-state management (READY/PENDING/FAILED) with clear transitions:
- READY: Empty container or successfully bootstrapped
- PENDING: Services registered, bootstrap required
- FAILED: Bootstrap failed, recovery needed
โ๏ธ Atomic Bootstrap Operations: All-or-nothing bootstrap with complete state reversion on failure.
๐ Graph-Based Analysis: Leverage loryth.common.collections.graph for both cycle detection and dependency ordering.
๐ Reflection-Driven Dependencies: Fresh dependency analysis during bootstrap using reflection system.
3.2 Bootstrap Flow Architecture¶
graph TD
A[Container Created<br/>Status: READY] --> B[Service Registration]
B --> C[Status: PENDING]
C --> D[First Resolve Call]
D --> E{Status Check}
E -->|PENDING| F[Trigger Bootstrap]
E -->|READY| G[Direct Resolution]
E -->|FAILED| H[โ Bootstrap Error]
F --> I[Build Dependency Graph<br/>AdjacencyListGraph]
I --> J[Topological Sort<br/>Cycle Detection]
J -->|Success|K[Initialize Singletons<br/>Dependency Order]
J -->|Cycle Found|L[โ Cycle Error]
K --> M[Status: READY<br/>Cache Populated]
M --> N[โ
Service Resolved]
L --> O[Status: FAILED<br/>Cache Cleared]
O --> P[โ Bootstrap Failed]
G --> N
classDef statusNode fill: none, stroke: #2196f3, stroke-width: 2px, color: #ffffff
classDef processNode fill: none, stroke: #4caf50, stroke-width: 2px, color: #ffffff
classDef errorNode fill: none, stroke: #f44336, stroke-width: 2px, color: #ffffff
classDef decisionNode fill: none, stroke: #ff9800, stroke-width: 2px, color: #ffffff
class A, C,M, O statusNode
class B, D, F, I, K, G, N processNode
class H, L, P errorNode
class E, J decisionNode 3.3 Component Architecture¶
| Component | Purpose | Key Features |
|---|---|---|
ContainerStatus | State management enum | READY/PENDING/FAILED transitions |
BootstrapManager | Orchestrates bootstrap lifecycle | Status transitions, error handling |
DependencyCycleDetector | Graph-based dependency analysis | Uses AdjacencyListGraph, topological_sort() |
SingletonInitializer | Ordered singleton resolution | Dependency-first initialization |
DiMetrics | Bootstrap observability | Performance tracking, diagnostics |
3.4 State Management & Recovery¶
The container lifecycle is managed through clear state transitions:
- Registration Impact: Any service registration transitions container from READY โ PENDING
- Bootstrap Success: PENDING โ READY with populated singleton cache
- Bootstrap Failure: PENDING โ FAILED with complete state reversion
- Recovery Mechanism: New registration after failure enables FAILED โ PENDING transition
3.5 Thread Safety & Concurrency¶
Bootstrap operations are designed for safe concurrent access:
- Reentrant Locking:
threading.RLock()enables same-thread resolve calls during bootstrap - Serialized Access: Multiple threads block until bootstrap completion
- Atomic State Changes: Container status and cache modifications are atomic
- Concurrent Resolution: Post-bootstrap resolution is fully concurrent
3.6 Integration with Existing Systems¶
The bootstrap system integrates seamlessly with existing components:
- Phase 1 Compatibility: All existing registration and resolution APIs unchanged
- Reflection Integration: Leverages
loryth.common.reflectionfor dependency analysis - Graph Collection: Uses
loryth.common.collections.graphfor cycle detection and ordering - Independent Metrics: Simple DI metrics system separate from reflection metrics
๐ 4. Implementation Details¶
4.1 Enhanced DiContainer Architecture¶
from enum import Enum
class ContainerStatus(Enum):
"""Container bootstrap status."""
PENDING = "pending" # Services registered, bootstrap needed
READY = "ready" # Bootstrap completed successfully
FAILED = "failed" # Bootstrap failed, recovery needed
class DiContainer:
def __init__(self) -> None:
self._items: list[DiContainerItem[Any]] = []
self._cache: dict[type, Any] = {}
self._bootstrap_manager = BootstrapManager(self)
self._bootstrap_lock = threading.RLock()
self._status = ContainerStatus.READY # Start ready (no services)
def bootstrap(self) -> None:
"""Manually trigger bootstrap process."""
with self._bootstrap_lock:
if self._status == ContainerStatus.READY:
return # Already bootstrapped
try:
self._bootstrap_manager.bootstrap()
self._status = ContainerStatus.READY
except Exception as e:
self._status = ContainerStatus.FAILED
# Revert to pre-bootstrap state
self._cache.clear()
raise
def resolve[T](self, service_type: type[T]) -> T:
"""Resolve service with automatic bootstrap."""
# Trigger bootstrap if needed
if self._status == ContainerStatus.PENDING:
self.bootstrap()
elif self._status == ContainerStatus.FAILED:
raise BootstrapError("Container in failed state, cannot resolve services")
# Existing resolution logic from Phase 1
return self._resolve_service(service_type)
def validate_dependencies(self) -> None:
"""Validate dependency graph without bootstrapping."""
detector = DependencyCycleDetector(self._dependencies)
cycles = detector.detect_cycles()
if cycles:
raise DependencyCycleError(f"Circular dependencies detected: {cycles}")
4.2 Bootstrap Manager Implementation¶
class BootstrapManager:
def __init__(self, container: DiContainer) -> None:
self._container = container
self._validator = BootstrapValidator(container)
self._cycle_detector = DependencyCycleDetector()
self._singleton_initializer = SingletonInitializer(container)
def bootstrap(self) -> None:
"""Execute complete bootstrap process."""
try:
# Phase 1: Validate dependency graph
self._validate_dependencies()
# Phase 2: Detect circular dependencies
self._detect_cycles()
# Phase 3: Initialize all singletons
self._initialize_singletons()
except Exception as e:
# Bootstrap failure should be clear and actionable
raise BootstrapError(f"Bootstrap failed: {e}") from e
def _validate_dependencies(self) -> None:
"""Validate all registered services have resolvable dependencies."""
self._validator.validate_all_dependencies()
def _detect_cycles(self) -> None:
"""Detect and report circular dependencies."""
cycles = self._cycle_detector.detect_cycles(self._container._dependencies)
if cycles:
formatted_cycles = self._format_cycle_errors(cycles)
raise DependencyCycleError(f"Circular dependencies detected:\n{formatted_cycles}")
def _initialize_singletons(self) -> None:
"""Resolve all registered singleton services."""
singleton_types = self._get_singleton_types()
self._singleton_initializer.initialize_all(singleton_types)
def _get_singleton_types(self) -> list[type]:
"""Get all service types registered as singletons."""
return [
item.type_ for item in self._container._items
if item.lifecycle == ServiceLifecycle.SINGLETON
]
4.3 Dependency Cycle Detection¶
from loryth.common.collections.graph import AdjacencyListGraph, topological_sort
class DependencyCycleDetector:
def __init__(self) -> None:
self._graph: AdjacencyListGraph[type, None] = AdjacencyListGraph()
def build_dependency_graph(self, container: "DiContainer") -> None:
"""Build dependency graph from container's registered services."""
# Add all service types as nodes
for item in container._items:
if not self._graph.has_node(item.type_):
self._graph.add_node(item.type_)
# Analyze dependencies for each service and add edges
for item in container._items:
dependencies = self._analyze_service_dependencies(container, item)
for dep_type in dependencies:
if self._graph.has_node(dep_type):
# Edge from service to its dependency
self._graph.add_edge(item.type_, dep_type, None)
def detect_cycle_via_topological_sort(self) -> None:
"""Detect cycles using topological sort - throws if cycle exists."""
try:
topological_sort(self._graph)
except ValueError as e:
if "cycle" in str(e).lower():
raise DependencyCycleError("Circular dependency detected in service graph")
raise
def get_topological_order(self) -> list[type]:
"""Get services in dependency order (dependencies first)."""
return list(topological_sort(self._graph))
def _analyze_service_dependencies(self, container: "DiContainer", item: DiContainerItem) -> list[type]:
"""Analyze dependencies for a specific service using reflection."""
if item.lifecycle == ServiceLifecycle.SINGLETON and callable(item.provider):
# For type-based services, analyze constructor dependencies
# This will be implemented in Phase 2.2
return container._get_service_dependencies(item.type_)
return []
4.4 Singleton Initialization¶
class SingletonInitializer:
def __init__(self, container: DiContainer, cycle_detector: DependencyCycleDetector) -> None:
self._container = container
self._cycle_detector = cycle_detector
def initialize_all_singletons(self) -> None:
"""Initialize all singleton services in dependency order."""
# Get topological order from cycle detector (dependencies first)
ordered_types = self._cycle_detector.get_topological_order()
# Filter to only singleton services
singleton_types = [
service_type for service_type in ordered_types
if self._is_singleton_service(service_type)
]
for service_type in singleton_types:
try:
# Use container's resolve method to leverage existing logic
self._container._resolve_service(service_type)
except Exception as e:
raise SingletonInitializationError(
f"Failed to initialize singleton {service_type.__name__}: {e}"
) from e
def _is_singleton_service(self, service_type: type) -> bool:
"""Check if service type is registered as singleton."""
item = self._container._find_provider(service_type)
return item is not None and item.lifecycle == ServiceLifecycle.SINGLETON
4.5 Container Status Management¶
The container uses a three-state status enum to track bootstrap lifecycle:
- READY: Container has no services or is successfully bootstrapped
- PENDING: Services registered, bootstrap required before resolution
- FAILED: Bootstrap failed, container unusable until recovery
Status transitions:
- Initial state:
READY(empty container) - On registration:
READYโPENDING - On successful bootstrap:
PENDINGโREADY - On bootstrap failure:
PENDINGโFAILED - On recovery (new registration):
FAILEDโPENDING
4.6 Dependency Graph Construction¶
Bootstrap builds dependency graph fresh using loryth.common.collections.graph.AdjacencyListGraph:
- Graph Construction: Add all service types as nodes, analyze dependencies via reflection, add edges
- Cycle Detection: Use
topological_sort()from collections - throwsValueErrorif cycles exist - Topological Ordering: Get dependency-first resolution order from same topological sort
- Performance: Single graph construction covers both cycle detection and ordering
4.7 Bootstrap Failure Recovery¶
Atomic bootstrap operations with complete state reversion:
- Success: Cache populated, status โ
READY - Failure: Cache cleared, status โ
FAILED, preserve pre-bootstrap registrations - Recovery: Allow new registrations to reset status โ
PENDING
4.8 DI Metrics System¶
Simple, comprehensive metrics tracking separate from reflection system:
Tracked Metrics:
- Bootstrap calls count and duration
- Number of services (total, singletons, transients)
- Average service initialization duration
- Number of resolutions and average duration
- Per-service initialization details and timing
- Cycle detection attempts and results
Design Philosophy:
- Evaluate alternative to reflection metrics
- Simple data collection without complex infrastructure
- Focus on actionable debugging information
4.9 Graph Collection Integration¶
Leverage existing loryth.common.collections.graph for dependency analysis:
- Cycle Detection: Use
topological_sort()- throws on cycles (no custom DFS needed) - Dependency Ordering: Same topological sort provides correct initialization order
- Graph Type:
AdjacencyListGraph[type, None]for service dependencies - Performance: O(V + E) complexity for both cycle detection and ordering
โ๏ธ 5. Semantics¶
5.1 Container Status Transitions¶
- Initial State:
READY(empty container, no services registered) - Registration Effect: Any service registration transitions
READYโPENDING - Bootstrap Success:
PENDINGโREADY(all singletons cached) - Bootstrap Failure:
PENDINGโFAILED(cache cleared, registrations preserved) - Recovery: New registration after failure transitions
FAILEDโPENDING
5.2 Bootstrap Triggers¶
- Automatic: First call to
resolve(),resolve_all(), ortry_resolve()when status isPENDING - Manual: Explicit call to
bootstrap()when status isPENDING - Failed State: Resolution calls on
FAILEDstatus throwBootstrapError - Ready State: Resolution calls on
READYstatus proceed without bootstrap
5.3 Bootstrap Process Order¶
- Graph Construction: Build
AdjacencyListGraphwith service dependencies via reflection - Cycle Detection: Use
topological_sort()- throwsValueErrorif cycles exist - Singleton Initialization: Resolve singletons in topological order (dependencies first)
- Factory Execution: Execute singleton factories during initialization
- Cache Population: Store resolved singletons in container cache
5.4 Atomic Bootstrap Operations¶
- All-or-Nothing: Complete success or complete failure with state reversion
- State Reversion: Failed bootstrap clears cache, preserves pre-bootstrap registrations
- Status Management: Failure sets status to
FAILED, success sets toREADY - Error Propagation: Original exception re-thrown after state cleanup
5.5 Thread Safety¶
- Bootstrap Lock:
threading.RLock()serializes bootstrap and resolution operations - Reentrant Operations: Same thread can call resolve during bootstrap
- Concurrent Protection: Multiple threads block until bootstrap completes
- Cache Consistency: Singleton cache remains consistent across concurrent access
๐งช 6. Examples¶
6.1 Automatic Bootstrap¶
from loryth.common.di import Container
# Register services
container = Container()
container.register_singleton(UserRepository, SqlUserRepository)
container.register_singleton(UserService, UserService) # depends on UserRepository
# First resolve triggers automatic bootstrap
user_service = container.resolve(UserService) # Bootstrap happens here
6.2 Manual Bootstrap¶
# Register services
container.register_singleton(UserRepository, SqlUserRepository)
container.register_singleton(UserService, UserService)
# Manual bootstrap for early validation
try:
container.bootstrap() # All singletons resolved and validated
print("Bootstrap successful - all dependencies valid")
except DependencyCycleError as e:
print(f"Circular dependency detected: {e}")
except BootstrapError as e:
print(f"Bootstrap failed: {e}")
6.3 Dependency Validation¶
# Register services with circular dependency
container.register_singleton(ServiceA, ServiceA) # depends on ServiceB
container.register_singleton(ServiceB, ServiceB) # depends on ServiceA
# Validate without initializing
try:
container.validate_dependencies()
except DependencyCycleError as e:
print(f"Validation failed: {e}")
# Output: "Circular dependencies detected: ServiceA -> ServiceB -> ServiceA"
โ 7. Acceptance Criteria¶
- โณ
bootstrap()method resolves all registered singletons and caches them - โณ Automatic bootstrap triggered on first resolve call
- โณ
validate_dependencies()detects circular dependencies without initialization - โณ Bootstrap process is idempotent - multiple calls are safe
- โณ Thread-safe bootstrap with proper locking mechanisms
- โณ Clear error messages for circular dependencies with service names
- โณ Bootstrap failure prevents container usage until reconfiguration
- โณ Topological sorting ensures dependencies are resolved before dependents
- โณ Singleton initialization happens in correct dependency order
- โณ Manual bootstrap option for early validation scenarios
๐งช 8. Test Matrix¶
8.1 Unit Test Coverage¶
Container Status Management¶
- โณ Initial State: Container starts in READY status with empty cache
- โณ Registration Transitions: READY โ PENDING on service registration
- โณ Bootstrap Success: PENDING โ READY with populated cache
- โณ Bootstrap Failure: PENDING โ FAILED with cleared cache
- โณ Recovery Transitions: FAILED โ PENDING on new registration
Bootstrap Manager¶
- โณ Manual Bootstrap: Explicit
bootstrap()call succeeds - โณ Automatic Bootstrap: First resolve triggers bootstrap
- โณ Idempotent Bootstrap: Multiple bootstrap calls on READY container
- โณ Bootstrap Failure Handling: Exception propagation with state reversion
- โณ Status Validation: Bootstrap only runs when status is PENDING
Dependency Analysis¶
- โณ Graph Construction: AdjacencyListGraph built correctly from services
- โณ Simple Dependencies: Linear dependency chain (A โ B โ C)
- โณ Complex Dependencies: Diamond dependencies (A โ B,C โ D)
- โณ No Dependencies: Services with no constructor dependencies
- โณ Self-Registration: Service depends on interface it implements
Cycle Detection¶
- โณ Simple Cycle: Two-service cycle (A โ B โ A)
- โณ Complex Cycle: Multi-service cycle (A โ B โ C โ A)
- โณ Deep Cycle: Cycle in deep dependency chain
- โณ No Cycle Detection: Valid dependency graph passes
- โณ Error Handling: DependencyCycleError with clear message
Singleton Initialization¶
- โณ Dependency Order: Dependencies resolved before dependents
- โณ Factory Execution: Singleton factories executed during bootstrap
- โณ Cache Population: Resolved singletons stored in cache
- โณ Initialization Failure: Single service failure fails entire bootstrap
- โณ Mixed Lifecycles: Singletons and transients handled correctly
Thread Safety¶
- โณ Concurrent Bootstrap: Multiple threads trigger bootstrap safely
- โณ Bootstrap Blocking: Resolution blocks during bootstrap
- โณ Reentrant Resolution: Same thread can resolve during bootstrap
- โณ Lock Behavior: RLock allows reentrant bootstrap calls
- โณ Cache Consistency: Thread-safe cache access
Error Scenarios¶
- โณ Invalid Registration: Type mismatch registration fails
- โณ Missing Dependencies: Unregistered dependency detection
- โณ Factory Exceptions: Factory failure during bootstrap
- โณ Constructor Exceptions: Constructor failure during resolution
- โณ Failed State Resolution: Resolve calls on FAILED status throw
8.2 Integration Test Coverage¶
Complete Bootstrap Workflows¶
- โณ End-to-End Success: Registration โ Bootstrap โ Resolution
- โณ Automatic Bootstrap Flow: Registration โ First Resolve โ Success
- โณ Manual Bootstrap Flow: Registration โ Manual Bootstrap โ Resolution
- โณ Bootstrap Recovery: Failure โ New Registration โ Retry โ Success
- โณ Mixed Service Types: Singletons, transients, factories, instances
Complex Dependency Scenarios¶
- โณ Deep Dependency Chains: 5+ level dependency hierarchies
- โณ Wide Dependency Trees: Services with multiple dependencies
- โณ Shared Dependencies: Multiple services depend on same service
- โณ Circular Reference Detection: Complex circular dependency scenarios
- โณ Partial Dependency Resolution: Some services resolvable, others not
Performance & Concurrency¶
- โณ Concurrent Access Patterns: Multiple threads accessing container
- โณ Bootstrap Performance: Large service graphs (50+ services)
- โณ Memory Usage: Bootstrap impact on container memory
- โณ Metrics Collection: Bootstrap metrics accuracy
- โณ Thread Contention: High-concurrency bootstrap scenarios
Integration with Phase 1¶
- โณ API Compatibility: All Phase 1 APIs work unchanged
- โณ Existing Container Migration: Phase 1 โ Phase 2 upgrade
- โณ Mixed Resolution: resolve(), resolve_all(), try_resolve()
- โณ Cache Behavior: Singleton caching across resolution methods
- โณ Registration Compatibility: All registration types supported
Reflection Integration¶
- โณ Constructor Analysis: Dependency extraction via reflection
- โณ Type Validation: Service type compatibility checking
- โณ Generic Types: Generic service registration and resolution
- โณ Protocol Support: Protocol-based service registration
- โณ Error Integration: Reflection errors during bootstrap
8.3 Test Organization¶
Unit Tests Location¶
tests/unit/di/bootstrap/
โโโ test_container_status.py
โโโ test_bootstrap_manager.py
โโโ test_dependency_analysis.py
โโโ test_cycle_detection.py
โโโ test_singleton_initialization.py
โโโ test_thread_safety.py
โโโ test_error_scenarios.py
Integration Tests Location¶
tests/integration/di/bootstrap/
โโโ test_bootstrap_workflows.py
โโโ test_complex_dependencies.py
โโโ test_performance_concurrency.py
โโโ test_phase1_integration.py
โโโ test_reflection_integration.py
Test Helpers & Resources¶
tests/resources/di/bootstrap/
โโโ simple_services.py # Basic service classes
โโโ complex_dependencies.py # Complex dependency scenarios
โโโ circular_services.py # Services with circular dependencies
โโโ performance_services.py # Large service graphs for testing
๐ 9. Rollout and Migration¶
9.1 Implementation Phases¶
Phase 2.1: Bootstrap Manager Infrastructure & Metrics
- Implement
BootstrapManagerclass with basic lifecycle - Add
ContainerStatusenum with three-state management (READY/PENDING/FAILED) - Implement bootstrap trigger integration in resolve methods
- Create simple DI metrics system with comprehensive tracking
- Container status transitions and state management
Phase 2.2: Dependency Analysis & Graph Integration
- Implement
DependencyCycleDetectorusingloryth.common.collections.graph - Build dependency graph fresh during bootstrap using
AdjacencyListGraph - Integrate
topological_sort()for cycle detection (throws on cycles) - Build dependency analysis via reflection for constructor inspection
Phase 2.3: Singleton Initialization & Thread Safety
- Implement
SingletonInitializerusing topological ordering from graph - Add thread-safe bootstrap with
threading.RLock() - Atomic bootstrap operations with state reversion on failure
- Factory execution during bootstrap for singleton lifecycles
- Per-service initialization with detailed error reporting
Phase 2.4: Enhanced Observability & Error Handling
- Complete metrics integration with per-service timing and details
- Bootstrap-specific exception hierarchy (BootstrapError, etc.)
- Enhanced error reporting with dependency chain information
- Performance monitoring and diagnostic capabilities
9.2 Backward Compatibility¶
- All Phase 1 functionality remains unchanged
- Bootstrap is automatic and transparent to existing code
- No breaking changes to registration or resolution APIs
โ ๏ธ 10. Risks and Mitigations¶
10.1 Performance Risk¶
Risk: Bootstrap overhead for simple applications with few dependencies Mitigation: Benchmark bootstrap time, provide manual control options
10.2 Deadlock Risk¶
Risk: Thread deadlock during concurrent bootstrap attempts Mitigation: Use RLock for reentrant locking, comprehensive deadlock testing
10.3 Memory Usage Risk¶
Risk: Increased memory usage from early singleton initialization Mitigation: Provide lazy initialization options, memory usage monitoring
๐ 11. Progress¶
Legend: โ = completed, ๐ง = in progress, โณ = pending, โ = cancelled
Phase 2.1: Bootstrap Manager Infrastructure & Metrics¶
- โ
Implement
BootstrapManagerclass with lifecycle management - โ
Add
ContainerStatusenum (READY/PENDING/FAILED) - โ
Integrate bootstrap triggers in
resolve(),resolve_all(),try_resolve() - โ Create DI metrics system with comprehensive tracking
- โ Implement container status transitions
Phase 2.2: Dependency Analysis & Graph Integration¶
- โ
Implement
DependencyCycleDetectorusing collections graph - โ
Build dependency graph with
AdjacencyListGraph[type, None] - โ
Integrate
topological_sort()for cycle detection - โ Implement reflection-based dependency analysis
Phase 2.3: Singleton Initialization & Thread Safety¶
- โ Implement
SingletonInitializerwith graph ordering - NOT IMPLEMENTED (functionality exists in BootstrapManager) - ๐ง Add thread-safe bootstrap with
threading.RLock()- PARTIALLY IMPLEMENTED - ๐ง Implement atomic operations with state reversion - PARTIALLY IMPLEMENTED
- โ Add factory execution for singleton lifecycles (implemented in BootstrapManager)
Phase 2.4: Enhanced Observability & Error Handling¶
- โ Complete per-service metrics and timing
- โ Implement bootstrap exception hierarchy
- โ Add enhanced error reporting with dependency chains
- โ Create comprehensive unit and integration tests
๐ 12. Changelog¶
- 2025-10-02: Initial draft technical design created
- 2025-10-03: Enhanced with container status enum, graph collection integration, and comprehensive implementation details
- 2025-10-03: โ Phase 2.1 COMPLETED - Implemented bootstrap manager infrastructure with comprehensive test suite (67 test scenarios, 305 total tests passing)
- 2025-10-03: โ Phase 2.2 COMPLETED - Implemented dependency analysis and graph integration with cycle detection
- 2025-10-03: ๐ง Phase 2.3 IN PROGRESS - Singleton initialization functionality exists in BootstrapManager (not separate class), thread safety partially implemented
- 2025-10-03: โ Phase 2.4 COMPLETED - Enhanced observability and error handling
- 2025-10-03: ๐ ANALYSIS COMPLETED - Current implementation status reviewed and gaps identified
- 2025-10-03: ๐ IMPLEMENTATION PLAN CREATED - Comprehensive implementation plan created to address gaps ( see 010-di-implementation-plan.md)
- 2025-10-03: ๐ SUMMARY DOCUMENT CREATED - Analysis summary created (see 010-di-summary.md)
๐ 13. Glossary¶
- Bootstrap: Process of initializing the DI container, detecting cycles, and resolving all singletons in dependency order
- Container Status: Three-state enum tracking bootstrap lifecycle (READY/PENDING/FAILED)
- Dependency Cycle: Circular dependency where services depend on each other directly or indirectly
- Dependency Graph: Directed graph representing service dependencies, built using
AdjacencyListGraph[type, None] - Topological Sort: Algorithm from
loryth.common.collections.graphthat orders services by dependencies and detects cycles - Atomic Bootstrap: All-or-nothing bootstrap operation that reverts state completely on any failure
- Singleton Initialization: Process of creating and caching singleton service instances in dependency order
- State Reversion: Recovery mechanism that clears cache and preserves only pre-bootstrap registrations on failure
- Bootstrap Trigger: Automatic bootstrap initiation on first resolve call when container status is PENDING
- DI Metrics: Simple metrics system tracking bootstrap performance, service counts, and initialization timing