4. Solution Strategy¶
4.1 Top-Level Decomposition¶
Primary Decomposition: Domain-Driven Design with 4 bounded contexts.
Rationale: Separating concerns by domain responsibility enables: - Clear ownership of functionality - Independent development and testing - Maintainable codebase with explicit boundaries - Scalable architecture for future enhancements
graph TB
subgraph "PopUpSim - 4 Bounded Contexts"
CFG["Configuration Context<br/>File loading & validation<br/>Pydantic models"]
RWF["Retrofit Workflow Context<br/>Core simulation logic<br/>SimPy coordinators"]
RLY["Railway Infrastructure Context<br/>Track management<br/>Domain aggregates"]
EXT["External Trains Context<br/>Train arrivals<br/>Event publishing"]
end
CFG -->|Scenario| RWF
CFG -->|Scenario| RLY
CFG -->|Scenario| EXT
RLY <-->|Track state| RWF
EXT -->|Events| RWF
classDef context fill:#e1f5fe,stroke:#01579b,stroke-width:2px
class CFG,RWF,RLY,EXT context
Context Responsibilities¶
| Context | Core Responsibility | Key Components |
|---|---|---|
| Configuration | Load and validate scenario files | FileLoader, ConfigurationBuilder, Pydantic models |
| Retrofit Workflow | Execute simulation, coordinate wagon flow | 4 coordinators, domain services, resource managers |
| Railway Infrastructure | Manage track capacity and occupancy | TrackGroup, Track, TrackOccupancy, TrackSelector |
| External Trains | Handle train arrivals, create wagons | TrainSchedule, ExternalTrain, Wagon entities |
4.2 Technology Decisions¶
| Technology | Purpose | Rationale |
|---|---|---|
| SimPy | Discrete event simulation | Deterministic, Python-native, proven in POC |
| Pydantic 2.0 | Data validation | Type safety, excellent validation, performance |
| Pandas | CSV processing | Efficient data loading, train schedule parsing |
| Matplotlib | Visualization | Simple charts, no web server required |
| Typer | CLI interface | User-friendly command-line interface |
| uv | Package management | Fast, reliable dependency management |
4.3 Architectural Patterns¶
4.3.1 Bounded Contexts (DDD)¶
Each context has clear boundaries and responsibilities: - Configuration: Input boundary - loads external data - Retrofit Workflow: Core domain - simulation execution - Railway Infrastructure: Supporting domain - track management - External Trains: Supporting domain - wagon lifecycle
4.3.2 Layered Architecture¶
Within each context:
Application Layer → Coordinators, services, orchestration
Domain Layer → Entities, aggregates, domain services
Infrastructure Layer → SimPy adapters, resource managers
4.3.3 Coordinator Pattern¶
Retrofit Workflow uses 4 specialized coordinators: 1. ArrivalCoordinator - Process train arrivals 2. CollectionCoordinator - Move wagons to retrofit track 3. WorkshopCoordinator - Execute retrofit operations 4. ParkingCoordinator - Move completed wagons to parking
Each coordinator runs as independent SimPy process.
4.3.4 Domain Services (No SimPy Dependencies)¶
Business logic isolated from simulation framework: - BatchFormationService - Create wagon batches - RakeFormationService - Form/dissolve wagon rakes - TrainFormationService - Assemble trains - WorkshopSchedulingService - Schedule workshops - CouplingService - Calculate coupling times
Benefits: - Testable without SimPy - Reusable across contexts - Clear business logic
4.4 Integration Strategy¶
4.4.1 Event-Driven Communication¶
Contexts communicate via domain events: - TrainArrivedEvent - External Trains → Retrofit Workflow - WagonMovedEvent - Retrofit Workflow → Railway Infrastructure - SimulationLifecycleEvents - Broadcast to all contexts
4.4.2 Direct Dependencies¶
Some contexts have direct dependencies: - Retrofit Workflow queries Railway Infrastructure for track capacity - All contexts receive Scenario from Configuration
4.4.3 Single Source of Truth¶
- Wagons: External Trains Context owns wagon entities
- Tracks: Railway Infrastructure Context owns track state
- Simulation State: Retrofit Workflow Context coordinates execution
4.5 Simulation Execution Flow¶
sequenceDiagram
participant Main
participant Config
participant ExtTrains
participant Railway
participant Retrofit
Main->>Config: Load scenario
Config-->>Main: Validated scenario
Main->>Railway: Initialize tracks
Main->>ExtTrains: Set scenario
Main->>Retrofit: Initialize context
Main->>Retrofit: Start processes
Retrofit->>Retrofit: Start coordinators
ExtTrains->>Retrofit: TrainArrivedEvent
Retrofit->>Railway: Query track capacity
Railway-->>Retrofit: Available capacity
Retrofit->>Retrofit: Execute workflow
Retrofit-->>Main: Simulation complete
Main->>Retrofit: Export results
4.6 Key Design Decisions¶
4.6.1 Removed Legacy Code¶
Cleaned up unused infrastructure: - Removed step-by-step configuration building (API-driven) - Removed legacy workflow strategies - Removed analytics context (metrics in Retrofit Workflow) - Simplified ConfigurationBuilder to file loading only
4.6.2 Coordinator Configuration Pattern¶
Coordinators use configuration objects:
@dataclass
class CollectionCoordinatorConfig:
env: Environment
collection_queue: Store
retrofit_queue: Store
batch_service: BatchFormationService
track_selector: TrackSelectionService
locomotive_manager: LocomotiveResourceManager
# ... event publishers, etc.
Benefits: - Clear dependencies - Easy testing with mocks - Reduced constructor complexity
4.6.3 Resource Management¶
Three resource managers handle capacity: - LocomotiveResourceManager - SimPy Resource for locomotives - TrackCapacityManager - Track capacity and wagon placement - WorkshopResourceManager - SimPy Resource for workshop stations
4.6.4 Metrics Collection¶
Retrofit Workflow collects metrics during simulation: - Real-time event collection - Post-simulation aggregation - CSV export with summary statistics
4.7 Quality Attributes¶
4.7.1 Maintainability¶
- Clear context boundaries
- Domain services without framework dependencies
- Comprehensive type hints (MyPy strict mode)
- Consistent code formatting (Ruff)
4.7.2 Testability¶
- Unit tests for domain services
- Integration tests for coordinators
- Validation tests for full scenarios
- Mock-friendly architecture
4.7.3 Performance¶
- Deterministic simulation (reproducible results)
- Efficient track capacity queries
- Batch processing for locomotive utilization
- Minimal memory footprint
4.7.4 Extensibility¶
- New coordinators can be added
- Track selection strategies pluggable
- Event-driven allows new subscribers
- Configuration supports new parameters
4.8 Technology Stack¶
Python 3.13+ → Latest stable Python
SimPy → Discrete event simulation
Pydantic 2.0+ → Data validation
Pandas → CSV processing
Matplotlib → Visualization
Typer → CLI interface
uv → Package management
pytest → Testing framework
mypy → Static type checking
ruff → Linting and formatting
pylint → Code quality analysis
4.9 Deployment Model¶
Single Application Deployment: - Desktop application with CLI - File-based input/output - No web server required - No database required - Runs on Windows/Linux/macOS
Execution:
uv run python src/main.py --scenario path/to/scenario --output path/to/output
4.10 Future Enhancements¶
Potential extensions (not in current scope): - Web interface for configuration and visualization - Real-time simulation monitoring - Database persistence for large scenarios - Distributed simulation for massive scale - API for integration with other systems - Advanced optimization algorithms