|
| 1 | +# 🚀 ElixirScope Startup Architecture |
| 2 | + |
| 3 | +Understanding the Foundation Layer Initialization Flow |
| 4 | + |
| 5 | +## 1. 🔄 Application Startup Flow |
| 6 | + |
| 7 | +This shows the complete startup sequence from OTP Application boot to ready state. |
| 8 | + |
| 9 | +```mermaid |
| 10 | +sequenceDiagram |
| 11 | + participant OTP as "OTP Runtime" |
| 12 | + participant App as "Foundation.Application" |
| 13 | + participant Sup as "Foundation.Supervisor" |
| 14 | + participant Config as "Config GenServer" |
| 15 | + participant Events as "Events (Stateless)" |
| 16 | + participant Tel as "Telemetry (Stateless)" |
| 17 | + participant Main as "ElixirScope (Main API)" |
| 18 | + |
| 19 | + OTP->>App: "start/2" |
| 20 | + Note over App: "Phase 1: Supervision Tree" |
| 21 | + App->>App: "Create children list" |
| 22 | + App->>Sup: "Supervisor.start_link(children, opts)" |
| 23 | + |
| 24 | + Note over Sup: "Phase 2: Critical Services" |
| 25 | + Sup->>Config: "GenServer.start_link" |
| 26 | + Config->>Config: "init/1 - Build & Validate Config" |
| 27 | + Config-->>Sup: "{:ok, pid}" |
| 28 | + |
| 29 | + Note over App: "Phase 3: Stateless Components" |
| 30 | + App->>Events: "Events.initialize()" |
| 31 | + Events-->>App: ":ok" |
| 32 | + App->>Tel: "Telemetry.initialize()" |
| 33 | + Tel-->>App: ":ok" |
| 34 | + |
| 35 | + App-->>OTP: "{:ok, supervisor_pid}" |
| 36 | + |
| 37 | + Note over Main: "Phase 4: User API Ready" |
| 38 | + Main->>Main: "ElixirScope.initialize()" |
| 39 | + Main->>Config: "Foundation.initialize()" |
| 40 | + Config->>Config: "Already running ✓" |
| 41 | + Main-->>OTP: "System Ready 🟢" |
| 42 | +``` |
| 43 | + |
| 44 | +### 🎯 Key Insights |
| 45 | + |
| 46 | +- **Sequential Dependency:** Config must start first as other components depend on it |
| 47 | +- **Fail-Fast Design:** If Config validation fails, entire application stops |
| 48 | +- **Stateless Strategy:** Events & Telemetry are stateless - no supervision needed |
| 49 | +- **Two-Phase Init:** Supervision tree first, then stateless components |
| 50 | + |
| 51 | +--- |
| 52 | + |
| 53 | +## 2. 🏗️ Module Hierarchy & Responsibilities |
| 54 | + |
| 55 | +Shows the layered architecture and how modules delegate responsibilities. |
| 56 | + |
| 57 | +```mermaid |
| 58 | +graph TD |
| 59 | + subgraph "User API Layer" |
| 60 | + ES["ElixirScope<br/>📱 Main API"] |
| 61 | + end |
| 62 | + |
| 63 | + subgraph "Foundation Orchestration" |
| 64 | + FND["Foundation<br/>🎯 Coordinator"] |
| 65 | + end |
| 66 | + |
| 67 | + subgraph "OTP Application Layer" |
| 68 | + APP["Foundation.Application<br/>🚀 OTP Bootstrap"] |
| 69 | + SUP["Foundation.Supervisor<br/>👥 Process Management"] |
| 70 | + end |
| 71 | + |
| 72 | + subgraph "Core Services" |
| 73 | + CFG["Config<br/>⚙️ GenServer State"] |
| 74 | + EVT["Events<br/>📨 Stateless Utils"] |
| 75 | + TEL["Telemetry<br/>📊 Metrics Collection"] |
| 76 | + end |
| 77 | + |
| 78 | + subgraph "Support Systems" |
| 79 | + ERR["Error & ErrorContext<br/>🚨 Error Management"] |
| 80 | + UTL["Utils<br/>🔧 Common Utilities"] |
| 81 | + TYP["Types<br/>📝 Type Definitions"] |
| 82 | + end |
| 83 | + |
| 84 | + ES -->|"initialize(opts)"| FND |
| 85 | + ES -->|"Direct API calls"| CFG |
| 86 | + ES -->|"Direct API calls"| EVT |
| 87 | + |
| 88 | + FND -->|"orchestrates"| CFG |
| 89 | + FND -->|"orchestrates"| EVT |
| 90 | + FND -->|"orchestrates"| TEL |
| 91 | + |
| 92 | + APP -->|"supervises"| SUP |
| 93 | + SUP -->|"starts & monitors"| CFG |
| 94 | + APP -->|"initializes"| EVT |
| 95 | + APP -->|"initializes"| TEL |
| 96 | + |
| 97 | + CFG -->|"uses"| ERR |
| 98 | + EVT -->|"uses"| UTL |
| 99 | + TEL -->|"uses"| UTL |
| 100 | + |
| 101 | + classDef userAPI fill:#e1f5fe,color:#000 |
| 102 | + classDef foundation fill:#f3e5f5,color:#000 |
| 103 | + classDef otp fill:#e8f5e8,color:#000 |
| 104 | + classDef services fill:#fff3e0,color:#000 |
| 105 | + classDef support fill:#fce4ec,color:#000 |
| 106 | + |
| 107 | + class ES userAPI |
| 108 | + class FND foundation |
| 109 | + class APP,SUP otp |
| 110 | + class CFG,EVT,TEL services |
| 111 | + class ERR,UTL,TYP support |
| 112 | +``` |
| 113 | + |
| 114 | +### 🎯 Architectural Principles |
| 115 | + |
| 116 | +- **Separation of Concerns:** Each module has a single, clear responsibility |
| 117 | +- **Dependency Injection:** Foundation orchestrates without tight coupling |
| 118 | +- **OTP Compliance:** Proper supervision tree with restart strategies |
| 119 | +- **Support Layer:** Common utilities shared across all components |
| 120 | + |
| 121 | +--- |
| 122 | + |
| 123 | +## 3. ⚙️ Config Service Lifecycle |
| 124 | + |
| 125 | +Deep dive into Config GenServer lifecycle, validation, and error handling. |
| 126 | + |
| 127 | +```mermaid |
| 128 | +stateDiagram-v2 |
| 129 | + [*] --> Starting : "GenServer.start_link()" |
| 130 | + |
| 131 | + state Starting { |
| 132 | + [*] --> BuildConfig : "init/1 called" |
| 133 | + BuildConfig --> MergeEnv : "Load environment" |
| 134 | + MergeEnv --> MergeOpts : "Apply runtime opts" |
| 135 | + MergeOpts --> Validate : "build_config/1 complete" |
| 136 | + Validate --> ConfigReady : "validate/1 passes" |
| 137 | + Validate --> Failed : "validate/1 fails" |
| 138 | + Failed --> [*] : "{stop, reason}" |
| 139 | + } |
| 140 | + |
| 141 | + Starting --> Running : "{ok, config}" |
| 142 | + |
| 143 | + state Running { |
| 144 | + [*] --> Serving |
| 145 | + Serving --> Processing : "handle_call" |
| 146 | + Processing --> Validating : "update request" |
| 147 | + Validating --> Serving : "validation passes" |
| 148 | + Validating --> Serving : "validation fails (error returned)" |
| 149 | + Serving --> Serving : "get requests" |
| 150 | + } |
| 151 | + |
| 152 | + Running --> Crashed : "Exception/Error" |
| 153 | + Crashed --> Starting : "Supervisor restart" |
| 154 | + |
| 155 | + state "Graceful Degradation" as GD { |
| 156 | + [*] --> CacheHit : "ETS fallback" |
| 157 | + CacheHit --> PendingUpdates : "Queue changes" |
| 158 | + PendingUpdates --> RetryLoop : "Background process" |
| 159 | + } |
| 160 | + |
| 161 | + Crashed --> GD : "Service unavailable" |
| 162 | + GD --> Running : "Service restored" |
| 163 | +``` |
| 164 | + |
| 165 | +### 🎯 Config Service Features |
| 166 | + |
| 167 | +- **Validation-First:** Config must pass validation before becoming active |
| 168 | +- **Runtime Updates:** Only specific paths can be updated at runtime |
| 169 | +- **Graceful Degradation:** ETS cache provides fallback during restarts |
| 170 | +- **Fail-Fast Init:** Invalid config causes supervised restart |
| 171 | + |
| 172 | +--- |
| 173 | + |
| 174 | +## 4. 🚨 Error Handling & Recovery |
| 175 | + |
| 176 | +How errors propagate through the system and recovery mechanisms. |
| 177 | + |
| 178 | +```mermaid |
| 179 | +flowchart TD |
| 180 | + Start(["Operation Starts"]) --> Context["Create ErrorContext"] |
| 181 | + Context --> Operation["Execute with Context"] |
| 182 | + |
| 183 | + Operation --> Success{"Success?"} |
| 184 | + Success -->|"Yes"| Telemetry["Emit Success Metrics"] |
| 185 | + Success -->|"No"| ErrorType{"Error Type?"} |
| 186 | + |
| 187 | + ErrorType -->|"Exception"| CatchEx["Catch & Wrap Exception"] |
| 188 | + ErrorType -->|"Error Tuple"| WrapError["Enhance Error Context"] |
| 189 | + |
| 190 | + CatchEx --> StructError["Create Structured Error"] |
| 191 | + WrapError --> StructError |
| 192 | + StructError --> AddContext["Add Operation Context"] |
| 193 | + |
| 194 | + AddContext --> Severity{"Check Severity"} |
| 195 | + Severity -->|"Critical/High"| Escalate["Escalate Error"] |
| 196 | + Severity -->|"Medium/Low"| Retry{"Retryable?"} |
| 197 | + |
| 198 | + Retry -->|"Yes"| DelayCalc["Calculate Retry Delay"] |
| 199 | + Retry -->|"No"| Fallback["Check Fallback"] |
| 200 | + |
| 201 | + DelayCalc --> RetryOp["Retry Operation"] |
| 202 | + RetryOp --> Operation |
| 203 | + |
| 204 | + Fallback -->|"Available"| UseFallback["Use Cached/Default"] |
| 205 | + Fallback -->|"None"| ErrorReturn["Return Error"] |
| 206 | + |
| 207 | + Escalate --> ErrorReturn |
| 208 | + UseFallback --> LogWarning["Log Degraded Mode"] |
| 209 | + Telemetry --> Success2(["Success End"]) |
| 210 | + ErrorReturn --> Failure(["Failure End"]) |
| 211 | + LogWarning --> Degraded(["Degraded Success"]) |
| 212 | + |
| 213 | + classDef successPath fill:#d4edda,color:#000 |
| 214 | + classDef errorPath fill:#f8d7da,color:#000 |
| 215 | + classDef recoveryPath fill:#fff3cd,color:#000 |
| 216 | + |
| 217 | + class Start,Context,Operation,Telemetry,Success2 successPath |
| 218 | + class ErrorType,CatchEx,WrapError,StructError,AddContext,Escalate,ErrorReturn,Failure errorPath |
| 219 | + class Retry,DelayCalc,RetryOp,Fallback,UseFallback,LogWarning,Degraded recoveryPath |
| 220 | +``` |
| 221 | + |
| 222 | +### 🎯 Error Handling Strategy |
| 223 | + |
| 224 | +- **Context Preservation:** ErrorContext tracks operation breadcrumbs |
| 225 | +- **Structured Errors:** Hierarchical error codes with severity levels |
| 226 | +- **Intelligent Retry:** Different retry strategies based on error type |
| 227 | +- **Graceful Degradation:** Fallback mechanisms maintain service availability |
| 228 | + |
| 229 | +--- |
| 230 | + |
| 231 | +## 5. 🔗 Service Dependencies & Communication |
| 232 | + |
| 233 | +How services communicate and depend on each other during runtime. |
| 234 | + |
| 235 | +```mermaid |
| 236 | +graph TD |
| 237 | + subgraph "Client Layer" |
| 238 | + CLI["Client Code"] |
| 239 | + end |
| 240 | + |
| 241 | + subgraph "API Layer" |
| 242 | + ES["ElixirScope API"] |
| 243 | + end |
| 244 | + |
| 245 | + subgraph "Foundation Layer" |
| 246 | + FND["Foundation Coordinator"] |
| 247 | + end |
| 248 | + |
| 249 | + subgraph "Service Layer" |
| 250 | + CFG["Config Service<br/>🟢 GenServer"] |
| 251 | + EVT["Events<br/>🔵 Stateless"] |
| 252 | + TEL["Telemetry<br/>🔵 Stateless"] |
| 253 | + end |
| 254 | + |
| 255 | + subgraph "Fallback Layer" |
| 256 | + ETS[("ETS Cache")] |
| 257 | + DEF["Default Config"] |
| 258 | + RET["Retry Queue"] |
| 259 | + end |
| 260 | + |
| 261 | + CLI -->|"1. ElixirScope.start()"| ES |
| 262 | + ES -->|"2. Foundation.initialize()"| FND |
| 263 | + |
| 264 | + FND -->|"3a. Config.initialize()"| CFG |
| 265 | + FND -->|"3b. Events.initialize()"| EVT |
| 266 | + FND -->|"3c. Telemetry.initialize()"| TEL |
| 267 | + |
| 268 | + CFG -.->|"Cache updates"| ETS |
| 269 | + CFG -.->|"Failed updates"| RET |
| 270 | + |
| 271 | + EVT -->|"Uses for IDs"| UTL["Utils"] |
| 272 | + TEL -->|"Uses for stats"| UTL |
| 273 | + |
| 274 | + ES -.->|"Direct calls"| CFG |
| 275 | + ES -.->|"Direct calls"| EVT |
| 276 | + |
| 277 | + CFG -->|"Service down"| ETS |
| 278 | + ETS -->|"Fallback values"| CLI |
| 279 | + |
| 280 | + RET -->|"Retry updates"| CFG |
| 281 | + DEF -->|"Emergency config"| CLI |
| 282 | + |
| 283 | + classDef client fill:#e3f2fd,color:#000 |
| 284 | + classDef api fill:#f3e5f5,color:#000 |
| 285 | + classDef foundation fill:#e8f5e8,color:#000 |
| 286 | + classDef services fill:#fff3e0,color:#000 |
| 287 | + classDef fallback fill:#fce4ec,color:#000 |
| 288 | + |
| 289 | + class CLI client |
| 290 | + class ES api |
| 291 | + class FND foundation |
| 292 | + class CFG,EVT,TEL services |
| 293 | + class ETS,DEF,RET fallback |
| 294 | +``` |
| 295 | + |
| 296 | +### 🎯 Communication Patterns |
| 297 | + |
| 298 | +- **Orchestrated Startup:** Foundation coordinates initialization sequence |
| 299 | +- **Direct Access:** Main API can call services directly for performance |
| 300 | +- **Graceful Degradation:** Multiple fallback layers for high availability |
| 301 | +- **Async Recovery:** Background processes handle retry and recovery |
| 302 | + |
| 303 | +--- |
| 304 | + |
| 305 | +## Key Architectural Insights Summary |
| 306 | + |
| 307 | +1. **Foundation as Orchestrator**: The Foundation module coordinates initialization but doesn't tightly couple services |
| 308 | + |
| 309 | +2. **Config-First Strategy**: Configuration service starts first and must be valid before the system is operational |
| 310 | + |
| 311 | +3. **Graceful Degradation**: Multiple layers of fallback ensure system availability even during service restarts |
| 312 | + |
| 313 | +4. **Error Context Propagation**: Sophisticated error handling preserves debugging context across the call stack |
| 314 | + |
| 315 | +5. **Mixed Service Types**: Combination of stateful (Config GenServer) and stateless (Events, Telemetry) services |
| 316 | + |
| 317 | +6. **Supervision Strategy**: Uses `:one_for_one` restart strategy where only failed processes restart |
| 318 | + |
| 319 | +7. **Validation-First Design**: All configuration must pass validation before becoming active |
| 320 | + |
| 321 | +8. **Emergency Fallback**: ETS-based caching provides service continuity during GenServer restarts |
0 commit comments