front-cpu 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/README.md +475 -0
  2. package/README.zh-CN.md +474 -0
  3. package/dist/Pipeline.d.ts +119 -0
  4. package/dist/Pipeline.d.ts.map +1 -0
  5. package/dist/Pipeline.js +373 -0
  6. package/dist/Pipeline.js.map +1 -0
  7. package/dist/debug.d.ts +3 -0
  8. package/dist/debug.d.ts.map +1 -0
  9. package/dist/debug.js +12 -0
  10. package/dist/debug.js.map +1 -0
  11. package/dist/index.d.ts +20 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +19 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/interfaces.d.ts +49 -0
  16. package/dist/interfaces.d.ts.map +1 -0
  17. package/dist/interfaces.js +8 -0
  18. package/dist/interfaces.js.map +1 -0
  19. package/dist/isa/index.d.ts +20 -0
  20. package/dist/isa/index.d.ts.map +1 -0
  21. package/dist/isa/index.js +26 -0
  22. package/dist/isa/index.js.map +1 -0
  23. package/dist/isa/types.d.ts +144 -0
  24. package/dist/isa/types.d.ts.map +1 -0
  25. package/dist/isa/types.js +10 -0
  26. package/dist/isa/types.js.map +1 -0
  27. package/dist/logging/CPUConsole.d.ts +105 -0
  28. package/dist/logging/CPUConsole.d.ts.map +1 -0
  29. package/dist/logging/CPUConsole.js +471 -0
  30. package/dist/logging/CPUConsole.js.map +1 -0
  31. package/dist/logging/CPUDebugger.d.ts +91 -0
  32. package/dist/logging/CPUDebugger.d.ts.map +1 -0
  33. package/dist/logging/CPUDebugger.js +166 -0
  34. package/dist/logging/CPUDebugger.js.map +1 -0
  35. package/dist/logging/CPUEventCollector.d.ts +90 -0
  36. package/dist/logging/CPUEventCollector.d.ts.map +1 -0
  37. package/dist/logging/CPUEventCollector.js +353 -0
  38. package/dist/logging/CPUEventCollector.js.map +1 -0
  39. package/dist/logging/CPULogger.d.ts +150 -0
  40. package/dist/logging/CPULogger.d.ts.map +1 -0
  41. package/dist/logging/CPULogger.js +336 -0
  42. package/dist/logging/CPULogger.js.map +1 -0
  43. package/dist/logging/index.d.ts +10 -0
  44. package/dist/logging/index.d.ts.map +1 -0
  45. package/dist/logging/index.js +16 -0
  46. package/dist/logging/index.js.map +1 -0
  47. package/dist/logging/runtime.d.ts +37 -0
  48. package/dist/logging/runtime.d.ts.map +1 -0
  49. package/dist/logging/runtime.js +42 -0
  50. package/dist/logging/runtime.js.map +1 -0
  51. package/dist/logging/stack-parser.d.ts +22 -0
  52. package/dist/logging/stack-parser.d.ts.map +1 -0
  53. package/dist/logging/stack-parser.js +144 -0
  54. package/dist/logging/stack-parser.js.map +1 -0
  55. package/dist/logging/types.d.ts +73 -0
  56. package/dist/logging/types.d.ts.map +1 -0
  57. package/dist/logging/types.js +47 -0
  58. package/dist/logging/types.js.map +1 -0
  59. package/dist/scheduling/ResourceStrategyRegistry.d.ts +61 -0
  60. package/dist/scheduling/ResourceStrategyRegistry.d.ts.map +1 -0
  61. package/dist/scheduling/ResourceStrategyRegistry.js +109 -0
  62. package/dist/scheduling/ResourceStrategyRegistry.js.map +1 -0
  63. package/dist/scheduling/index.d.ts +6 -0
  64. package/dist/scheduling/index.d.ts.map +1 -0
  65. package/dist/scheduling/index.js +5 -0
  66. package/dist/scheduling/index.js.map +1 -0
  67. package/dist/scheduling/types.d.ts +44 -0
  68. package/dist/scheduling/types.d.ts.map +1 -0
  69. package/dist/scheduling/types.js +5 -0
  70. package/dist/scheduling/types.js.map +1 -0
  71. package/dist/stages/EX.d.ts +17 -0
  72. package/dist/stages/EX.d.ts.map +1 -0
  73. package/dist/stages/EX.js +95 -0
  74. package/dist/stages/EX.js.map +1 -0
  75. package/dist/stages/IF.d.ts +41 -0
  76. package/dist/stages/IF.d.ts.map +1 -0
  77. package/dist/stages/IF.js +83 -0
  78. package/dist/stages/IF.js.map +1 -0
  79. package/dist/stages/RES.d.ts +17 -0
  80. package/dist/stages/RES.d.ts.map +1 -0
  81. package/dist/stages/RES.js +37 -0
  82. package/dist/stages/RES.js.map +1 -0
  83. package/dist/stages/SCH.d.ts +77 -0
  84. package/dist/stages/SCH.d.ts.map +1 -0
  85. package/dist/stages/SCH.js +270 -0
  86. package/dist/stages/SCH.js.map +1 -0
  87. package/dist/stages/WB.d.ts +19 -0
  88. package/dist/stages/WB.d.ts.map +1 -0
  89. package/dist/stages/WB.js +102 -0
  90. package/dist/stages/WB.js.map +1 -0
  91. package/dist/types.d.ts +111 -0
  92. package/dist/types.d.ts.map +1 -0
  93. package/dist/types.js +26 -0
  94. package/dist/types.js.map +1 -0
  95. package/dist/utils/InstructionCancellation.d.ts +31 -0
  96. package/dist/utils/InstructionCancellation.d.ts.map +1 -0
  97. package/dist/utils/InstructionCancellation.js +53 -0
  98. package/dist/utils/InstructionCancellation.js.map +1 -0
  99. package/dist/utils/abortable.d.ts +30 -0
  100. package/dist/utils/abortable.d.ts.map +1 -0
  101. package/dist/utils/abortable.js +76 -0
  102. package/dist/utils/abortable.js.map +1 -0
  103. package/dist/utils/request.d.ts +27 -0
  104. package/dist/utils/request.d.ts.map +1 -0
  105. package/dist/utils/request.js +96 -0
  106. package/dist/utils/request.js.map +1 -0
  107. package/package.json +74 -0
  108. package/src/Pipeline.ts +475 -0
  109. package/src/debug.ts +15 -0
  110. package/src/index.ts +67 -0
  111. package/src/interfaces.ts +53 -0
  112. package/src/isa/index.ts +34 -0
  113. package/src/isa/types.ts +178 -0
  114. package/src/logging/CPUConsole.md +843 -0
  115. package/src/logging/CPUConsole.ts +631 -0
  116. package/src/logging/CPUDebugger.ts +235 -0
  117. package/src/logging/CPUEventCollector.ts +418 -0
  118. package/src/logging/CPULogger.ts +435 -0
  119. package/src/logging/CPU_LOGGING_DESIGN.md +1319 -0
  120. package/src/logging/USAGE_GUIDE.md +505 -0
  121. package/src/logging/index.ts +21 -0
  122. package/src/logging/runtime.ts +96 -0
  123. package/src/logging/stack-parser.ts +168 -0
  124. package/src/logging/types.ts +101 -0
  125. package/src/scheduling/ResourceStrategyRegistry.ts +124 -0
  126. package/src/scheduling/index.ts +13 -0
  127. package/src/scheduling/types.ts +47 -0
  128. package/src/stages/EX.ts +121 -0
  129. package/src/stages/IF.ts +103 -0
  130. package/src/stages/RES.ts +46 -0
  131. package/src/stages/SCH.ts +331 -0
  132. package/src/stages/WB.ts +127 -0
  133. package/src/types.ts +118 -0
  134. package/src/utils/InstructionCancellation.ts +73 -0
  135. package/src/utils/abortable.ts +89 -0
  136. package/src/utils/request.ts +125 -0
@@ -0,0 +1,843 @@
1
+ # CPU Console - 实时控制台打印系统
2
+
3
+ **设计目标**: 为开发者提供直观、美观、实时的指令执行反馈
4
+ **核心原则**: 快速定位、分级显示、美观易读、零配置可用
5
+
6
+ ---
7
+
8
+ ## 📋 设计理念
9
+
10
+ ### 日志审计 vs 控制台打印
11
+
12
+ ```typescript
13
+ // CPULogger (审计系统)
14
+ // - 用途:事后分析、性能监控、问题排查
15
+ // - 特点:结构化、可查询、批量处理
16
+ // - 场景:找出所有执行超过100ms的指令、分析资源冲突
17
+
18
+ // CPUConsole (控制台系统)
19
+ // - 用途:实时查看指令是否正确执行
20
+ // - 特点:直观、美观、即时反馈
21
+ // - 场景:我拖动了任务,指令发了吗?成功了吗?
22
+ ```
23
+
24
+ ### 用户期望
25
+
26
+ 开发者希望在控制台中快速看到:
27
+
28
+ ```
29
+ ✅ [12:34:56.123] task.update → 执行成功 (125ms)
30
+ ├─ IF 0ms
31
+ ├─ SCH 0ms
32
+ ├─ EX 123ms (乐观更新 ✓ | 网络请求 ✓)
33
+ └─ WB 2ms
34
+
35
+ ❌ [12:34:56.456] schedule.update → 失败 (24ms)
36
+ ├─ 原因: database is locked
37
+ ├─ 已回滚乐观更新 ✓
38
+ └─ 建议: 后端并发控制问题
39
+ ```
40
+
41
+ ---
42
+
43
+ ## 🎨 CPUConsole 设计
44
+
45
+ ### 核心类
46
+
47
+ ```typescript
48
+ /**
49
+ * CPU 控制台打印系统
50
+ *
51
+ * 职责:
52
+ * 1. 实时打印指令执行过程
53
+ * 2. 美观的彩色输出
54
+ * 3. 分级别控制详细程度
55
+ * 4. 可折叠的详细信息
56
+ */
57
+ export class CPUConsole {
58
+ private enabled: boolean = true
59
+ private level: ConsoleLevel = ConsoleLevel.NORMAL
60
+ private filter: Set<string> = new Set() // 指令类型过滤
61
+
62
+ /**
63
+ * 控制台级别
64
+ */
65
+ enum ConsoleLevel {
66
+ SILENT = 0, // 不输出任何内容
67
+ MINIMAL = 1, // 只输出成功/失败
68
+ NORMAL = 2, // 输出关键阶段
69
+ VERBOSE = 3, // 输出所有细节
70
+ DEBUG = 4, // 输出调试信息(包括 payload)
71
+ }
72
+
73
+ /**
74
+ * 配置方法
75
+ */
76
+ setLevel(level: ConsoleLevel): void {
77
+ this.level = level
78
+ localStorage.setItem('cpu-console-level', level.toString())
79
+ }
80
+
81
+ setFilter(types: string[]): void {
82
+ this.filter = new Set(types)
83
+ localStorage.setItem('cpu-console-filter', JSON.stringify(types))
84
+ }
85
+
86
+ enable(): void {
87
+ this.enabled = true
88
+ }
89
+
90
+ disable(): void {
91
+ this.enabled = false
92
+ }
93
+
94
+ // ==================== 打印方法 ====================
95
+
96
+ /**
97
+ * 指令创建
98
+ */
99
+ onInstructionCreated(instruction: QueuedInstruction): void {
100
+ if (!this.shouldPrint(instruction.type)) return
101
+
102
+ if (this.level >= ConsoleLevel.NORMAL) {
103
+ console.log(
104
+ `%c🎯 ${this.formatTime()} %c${instruction.type}%c 指令创建`,
105
+ 'color: #666; font-size: 11px',
106
+ 'color: #3b82f6; font-weight: bold; background: #3b82f615; padding: 2px 6px; border-radius: 3px',
107
+ 'color: #666',
108
+ {
109
+ id: instruction.id,
110
+ correlationId: instruction.context.correlationId,
111
+ payload: this.level >= ConsoleLevel.DEBUG ? instruction.payload : '(use level=DEBUG to see)',
112
+ }
113
+ )
114
+ }
115
+ }
116
+
117
+ /**
118
+ * 指令成功
119
+ */
120
+ onInstructionSuccess(instruction: QueuedInstruction, duration: number): void {
121
+ if (!this.shouldPrint(instruction.type)) return
122
+
123
+ // 🎯 核心:折叠分组,方便查看
124
+ console.groupCollapsed(
125
+ `%c✅ ${this.formatTime()} %c${instruction.type}%c → 成功 %c${duration}ms`,
126
+ 'color: #666; font-size: 11px',
127
+ 'color: #10b981; font-weight: bold; background: #10b98115; padding: 2px 6px; border-radius: 3px',
128
+ 'color: #10b981',
129
+ 'color: #10b981; font-weight: bold'
130
+ )
131
+
132
+ // 显示流水线阶段
133
+ if (this.level >= ConsoleLevel.NORMAL) {
134
+ this.printPipelineStages(instruction)
135
+ }
136
+
137
+ // 显示详细信息
138
+ if (this.level >= ConsoleLevel.VERBOSE) {
139
+ this.printInstructionDetails(instruction)
140
+ }
141
+
142
+ console.groupEnd()
143
+ }
144
+
145
+ /**
146
+ * 指令失败
147
+ */
148
+ onInstructionFailure(
149
+ instruction: QueuedInstruction,
150
+ error: Error,
151
+ duration: number
152
+ ): void {
153
+ if (!this.shouldPrint(instruction.type)) return
154
+
155
+ // 🔥 失败时自动展开,方便排查
156
+ console.group(
157
+ `%c❌ ${this.formatTime()} %c${instruction.type}%c → 失败 %c${duration}ms`,
158
+ 'color: #666; font-size: 11px',
159
+ 'color: #ef4444; font-weight: bold; background: #ef444415; padding: 2px 6px; border-radius: 3px',
160
+ 'color: #ef4444',
161
+ 'color: #ef4444; font-weight: bold'
162
+ )
163
+
164
+ // 显示错误信息
165
+ console.error(`%c原因: ${error.message}`, 'color: #ef4444; font-weight: bold')
166
+
167
+ // 显示流水线阶段
168
+ this.printPipelineStages(instruction)
169
+
170
+ // 显示是否回滚
171
+ if (instruction.optimisticSnapshot) {
172
+ console.log('%c✓ 已回滚乐观更新', 'color: #f59e0b; font-weight: bold')
173
+ }
174
+
175
+ // 显示详细信息
176
+ if (this.level >= ConsoleLevel.VERBOSE) {
177
+ this.printInstructionDetails(instruction)
178
+ console.error('Error Stack:', error.stack)
179
+ }
180
+
181
+ // 🔥 智能建议
182
+ this.printSuggestions(instruction, error)
183
+
184
+ console.groupEnd()
185
+ }
186
+
187
+ /**
188
+ * 乐观更新应用
189
+ */
190
+ onOptimisticApplied(instruction: QueuedInstruction): void {
191
+ if (!this.shouldPrint(instruction.type)) return
192
+
193
+ if (this.level >= ConsoleLevel.VERBOSE) {
194
+ console.log(
195
+ `%c 🔄 ${this.formatTime()} 乐观更新已应用`,
196
+ 'color: #8b5cf6',
197
+ {
198
+ instructionId: instruction.id,
199
+ hasSnapshot: !!instruction.optimisticSnapshot,
200
+ }
201
+ )
202
+ }
203
+ }
204
+
205
+ /**
206
+ * 乐观更新回滚
207
+ */
208
+ onOptimisticRolledBack(instruction: QueuedInstruction, reason: string): void {
209
+ if (!this.shouldPrint(instruction.type)) return
210
+
211
+ // 回滚是重要事件,总是显示
212
+ if (this.level >= ConsoleLevel.MINIMAL) {
213
+ console.warn(
214
+ `%c⚠️ ${this.formatTime()} %c${instruction.type}%c 乐观更新已回滚`,
215
+ 'color: #666; font-size: 11px',
216
+ 'color: #f59e0b; font-weight: bold; background: #f59e0b15; padding: 2px 6px; border-radius: 3px',
217
+ 'color: #f59e0b',
218
+ {
219
+ instructionId: instruction.id,
220
+ reason,
221
+ }
222
+ )
223
+ }
224
+ }
225
+
226
+ /**
227
+ * 资源冲突
228
+ */
229
+ onSchedulerConflict(
230
+ instruction: QueuedInstruction,
231
+ conflictingWith: string[],
232
+ waitTime: number
233
+ ): void {
234
+ if (!this.shouldPrint(instruction.type)) return
235
+
236
+ if (this.level >= ConsoleLevel.VERBOSE) {
237
+ console.log(
238
+ `%c ⏳ ${this.formatTime()} 资源冲突,等待 ${waitTime}ms`,
239
+ 'color: #f59e0b',
240
+ {
241
+ instructionId: instruction.id,
242
+ conflictingWith,
243
+ }
244
+ )
245
+ }
246
+ }
247
+
248
+ /**
249
+ * 网络请求
250
+ */
251
+ onNetworkRequest(
252
+ instruction: QueuedInstruction,
253
+ method: string,
254
+ url: string
255
+ ): void {
256
+ if (!this.shouldPrint(instruction.type)) return
257
+
258
+ if (this.level >= ConsoleLevel.DEBUG) {
259
+ console.log(
260
+ `%c 🌐 ${this.formatTime()} ${method} ${url}`,
261
+ 'color: #06b6d4',
262
+ {
263
+ instructionId: instruction.id,
264
+ correlationId: instruction.context.correlationId,
265
+ }
266
+ )
267
+ }
268
+ }
269
+
270
+ /**
271
+ * 网络响应
272
+ */
273
+ onNetworkResponse(
274
+ instruction: QueuedInstruction,
275
+ status: number,
276
+ latency: number
277
+ ): void {
278
+ if (!this.shouldPrint(instruction.type)) return
279
+
280
+ if (this.level >= ConsoleLevel.DEBUG) {
281
+ const statusColor = status >= 200 && status < 300 ? '#10b981' : '#ef4444'
282
+ console.log(
283
+ `%c ← ${this.formatTime()} HTTP ${status} (${latency}ms)`,
284
+ `color: ${statusColor}`,
285
+ {
286
+ instructionId: instruction.id,
287
+ }
288
+ )
289
+ }
290
+ }
291
+
292
+ // ==================== 辅助方法 ====================
293
+
294
+ /**
295
+ * 打印流水线阶段
296
+ */
297
+ private printPipelineStages(instruction: QueuedInstruction): void {
298
+ const timestamps = instruction.timestamps
299
+
300
+ // 计算各阶段耗时
301
+ const stages = [
302
+ { name: 'IF', time: timestamps.IF },
303
+ { name: 'SCH', time: timestamps.SCH },
304
+ { name: 'EX', time: timestamps.EX },
305
+ { name: 'WB', time: timestamps.WB },
306
+ ]
307
+
308
+ let lastTime = timestamps.IF
309
+
310
+ console.log('%c流水线阶段:', 'color: #666; font-weight: bold')
311
+
312
+ for (const stage of stages) {
313
+ if (stage.time) {
314
+ const duration = stage.time - lastTime
315
+ const bar = this.createDurationBar(duration)
316
+
317
+ console.log(
318
+ ` %c${stage.name}%c ${bar} %c${duration}ms`,
319
+ 'color: #3b82f6; font-weight: bold; min-width: 30px',
320
+ 'color: #666',
321
+ 'color: #666; font-weight: bold'
322
+ )
323
+
324
+ lastTime = stage.time
325
+ }
326
+ }
327
+
328
+ // 特殊标记
329
+ if (instruction.optimisticSnapshot) {
330
+ console.log(' %c✓ 乐观更新', 'color: #8b5cf6')
331
+ }
332
+ }
333
+
334
+ /**
335
+ * 打印指令详情
336
+ */
337
+ private printInstructionDetails(instruction: QueuedInstruction): void {
338
+ console.log('%c详细信息:', 'color: #666; font-weight: bold')
339
+ console.table({
340
+ 'Instruction ID': instruction.id,
341
+ 'Correlation ID': instruction.context.correlationId,
342
+ 'Type': instruction.type,
343
+ 'Status': instruction.status,
344
+ 'Created At': new Date(instruction.timestamps.IF).toISOString(),
345
+ })
346
+
347
+ if (this.level >= ConsoleLevel.DEBUG) {
348
+ console.log('%cPayload:', 'color: #666; font-weight: bold', instruction.payload)
349
+
350
+ if (instruction.result) {
351
+ console.log('%cResult:', 'color: #666; font-weight: bold', instruction.result)
352
+ }
353
+ }
354
+ }
355
+
356
+ /**
357
+ * 打印智能建议
358
+ */
359
+ private printSuggestions(instruction: QueuedInstruction, error: Error): void {
360
+ const suggestions: string[] = []
361
+
362
+ // 根据错误类型给出建议
363
+ if (error.message.includes('database is locked')) {
364
+ suggestions.push('后端数据库锁定,检查写入许可是否正确获取')
365
+ }
366
+
367
+ if (error.message.includes('Network')) {
368
+ suggestions.push('网络错误,检查后端服务是否运行')
369
+ }
370
+
371
+ if (error.message.includes('timeout')) {
372
+ suggestions.push('请求超时,考虑增加超时时间或优化后端性能')
373
+ }
374
+
375
+ // 根据指令类型给出建议
376
+ const duration = instruction.timestamps.WB
377
+ ? instruction.timestamps.WB - instruction.timestamps.IF
378
+ : 0
379
+
380
+ if (duration > 1000) {
381
+ suggestions.push(`执行耗时 ${duration}ms,超过 1 秒,检查是否存在性能问题`)
382
+ }
383
+
384
+ if (suggestions.length > 0) {
385
+ console.log('%c💡 建议:', 'color: #f59e0b; font-weight: bold')
386
+ suggestions.forEach((s) => {
387
+ console.log(` • ${s}`)
388
+ })
389
+ }
390
+ }
391
+
392
+ /**
393
+ * 创建耗时条形图
394
+ */
395
+ private createDurationBar(duration: number): string {
396
+ const maxWidth = 20
397
+ const width = Math.min(Math.round(duration / 50), maxWidth)
398
+ const bar = '█'.repeat(width)
399
+
400
+ // 根据耗时着色
401
+ if (duration < 50) {
402
+ return `${bar}` // 绿色
403
+ } else if (duration < 200) {
404
+ return `${bar}` // 黄色
405
+ } else {
406
+ return `${bar}` // 红色
407
+ }
408
+ }
409
+
410
+ /**
411
+ * 格式化时间
412
+ */
413
+ private formatTime(): string {
414
+ const now = new Date()
415
+ return now.toLocaleTimeString('zh-CN', {
416
+ hour12: false,
417
+ hour: '2-digit',
418
+ minute: '2-digit',
419
+ second: '2-digit',
420
+ fractionalSecondDigits: 3,
421
+ })
422
+ }
423
+
424
+ /**
425
+ * 判断是否应该打印
426
+ */
427
+ private shouldPrint(instructionType: string): boolean {
428
+ if (!this.enabled) return false
429
+ if (this.level === ConsoleLevel.SILENT) return false
430
+ if (this.filter.size > 0 && !this.filter.has(instructionType)) return false
431
+ return true
432
+ }
433
+
434
+ // ==================== 便捷方法 ====================
435
+
436
+ /**
437
+ * 打印分隔线
438
+ */
439
+ printSeparator(title?: string): void {
440
+ if (!this.enabled) return
441
+
442
+ if (title) {
443
+ console.log(
444
+ `%c━━━━━━━━━━━━━━━━━━━━━━━━━━ ${title} ━━━━━━━━━━━━━━━━━━━━━━━━━━`,
445
+ 'color: #666; font-weight: bold'
446
+ )
447
+ } else {
448
+ console.log('%c━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', 'color: #666')
449
+ }
450
+ }
451
+
452
+ /**
453
+ * 打印统计信息
454
+ */
455
+ printStats(stats: {
456
+ total: number
457
+ success: number
458
+ failed: number
459
+ avgLatency: number
460
+ }): void {
461
+ if (!this.enabled) return
462
+
463
+ console.group('%c📊 流水线统计', 'color: #3b82f6; font-weight: bold; font-size: 14px')
464
+
465
+ console.log(
466
+ ` 总指令数: %c${stats.total}`,
467
+ 'color: #3b82f6; font-weight: bold'
468
+ )
469
+
470
+ console.log(
471
+ ` 成功: %c${stats.success} %c(${((stats.success / stats.total) * 100).toFixed(1)}%)`,
472
+ 'color: #10b981; font-weight: bold',
473
+ 'color: #666'
474
+ )
475
+
476
+ console.log(
477
+ ` 失败: %c${stats.failed} %c(${((stats.failed / stats.total) * 100).toFixed(1)}%)`,
478
+ 'color: #ef4444; font-weight: bold',
479
+ 'color: #666'
480
+ )
481
+
482
+ console.log(
483
+ ` 平均延迟: %c${stats.avgLatency.toFixed(0)}ms`,
484
+ 'color: #666; font-weight: bold'
485
+ )
486
+
487
+ console.groupEnd()
488
+ }
489
+ }
490
+
491
+ // 导出全局单例
492
+ export const cpuConsole = new CPUConsole()
493
+
494
+ // 导出枚举
495
+ export { ConsoleLevel }
496
+ ```
497
+
498
+ ---
499
+
500
+ ## 🎨 使用示例
501
+
502
+ ### 1. 在流水线中集成
503
+
504
+ ```typescript
505
+ // src/cpu/Pipeline.ts
506
+ import { cpuConsole } from './logging/CPUConsole'
507
+
508
+ export class Pipeline {
509
+ async dispatch(type: string, payload: any): Promise<void> {
510
+ const instruction = this.createInstruction(type, payload)
511
+
512
+ // 🎯 打印指令创建
513
+ cpuConsole.onInstructionCreated(instruction)
514
+
515
+ try {
516
+ await this.executeInstruction(instruction)
517
+
518
+ const duration = instruction.timestamps.WB - instruction.timestamps.IF
519
+
520
+ // 🎯 打印成功
521
+ cpuConsole.onInstructionSuccess(instruction, duration)
522
+ } catch (error) {
523
+ const duration = Date.now() - instruction.timestamps.IF
524
+
525
+ // 🎯 打印失败
526
+ cpuConsole.onInstructionFailure(instruction, error as Error, duration)
527
+ }
528
+ }
529
+ }
530
+ ```
531
+
532
+ ### 2. 在 EX 阶段集成
533
+
534
+ ```typescript
535
+ // src/cpu/stages/EX.ts
536
+ import { cpuConsole } from '../logging/CPUConsole'
537
+
538
+ export class ExecuteStage {
539
+ async execute(instruction: QueuedInstruction): Promise<void> {
540
+ // 应用乐观更新
541
+ if (isa.optimistic?.enabled) {
542
+ instruction.optimisticSnapshot = isa.optimistic.apply(
543
+ instruction.payload,
544
+ instruction.context
545
+ )
546
+
547
+ // 🎯 打印乐观更新
548
+ cpuConsole.onOptimisticApplied(instruction)
549
+ }
550
+
551
+ // 网络请求
552
+ if (isa.request) {
553
+ const url = typeof isa.request.url === 'function'
554
+ ? isa.request.url(instruction.payload)
555
+ : isa.request.url
556
+
557
+ // 🎯 打印网络请求
558
+ cpuConsole.onNetworkRequest(instruction, isa.request.method, url)
559
+
560
+ const startTime = Date.now()
561
+ const result = await executeRequest(isa.request, instruction.payload, instruction.context)
562
+ const latency = Date.now() - startTime
563
+
564
+ // 🎯 打印网络响应
565
+ cpuConsole.onNetworkResponse(instruction, 200, latency)
566
+
567
+ instruction.result = result
568
+ }
569
+ }
570
+ }
571
+ ```
572
+
573
+ ### 3. 在 WB 阶段集成
574
+
575
+ ```typescript
576
+ // src/cpu/stages/WB.ts
577
+ import { cpuConsole } from '../logging/CPUConsole'
578
+
579
+ export class WriteBackStage {
580
+ private rollbackOptimisticUpdate(instruction: QueuedInstruction): void {
581
+ const definition = ISA[instruction.type]
582
+
583
+ if (instruction.optimisticSnapshot && definition?.optimistic?.rollback) {
584
+ // 🎯 打印回滚
585
+ cpuConsole.onOptimisticRolledBack(
586
+ instruction,
587
+ '指令执行失败'
588
+ )
589
+
590
+ definition.optimistic.rollback(instruction.optimisticSnapshot)
591
+ }
592
+ }
593
+ }
594
+ ```
595
+
596
+ ### 4. 在 SCH 阶段集成
597
+
598
+ ```typescript
599
+ // src/cpu/stages/SCH.ts
600
+ import { cpuConsole } from '../logging/CPUConsole'
601
+
602
+ export class SchedulerStage {
603
+ private detectConflict(instruction: QueuedInstruction): boolean {
604
+ const conflicts = this.findConflictingInstructions(instruction)
605
+
606
+ if (conflicts.length > 0) {
607
+ // 🎯 打印资源冲突
608
+ cpuConsole.onSchedulerConflict(
609
+ instruction,
610
+ conflicts.map(i => i.id),
611
+ this.TICK_INTERVAL_MS
612
+ )
613
+
614
+ return true
615
+ }
616
+
617
+ return false
618
+ }
619
+ }
620
+ ```
621
+
622
+ ### 5. 控制台配置
623
+
624
+ ```typescript
625
+ // 开发环境:详细模式
626
+ if (import.meta.env.DEV) {
627
+ cpuConsole.setLevel(ConsoleLevel.VERBOSE)
628
+ }
629
+
630
+ // 生产环境:只看失败
631
+ if (import.meta.env.PROD) {
632
+ cpuConsole.setLevel(ConsoleLevel.MINIMAL)
633
+ }
634
+
635
+ // 只看特定指令
636
+ cpuConsole.setFilter(['schedule.update', 'task.create'])
637
+
638
+ // 完全关闭
639
+ cpuConsole.disable()
640
+ ```
641
+
642
+ ### 6. 在调试器中使用
643
+
644
+ ```typescript
645
+ // src/views/CPUDebugView.vue
646
+ <script setup lang="ts">
647
+ import { cpuConsole, ConsoleLevel } from '@/cpu/logging/CPUConsole'
648
+
649
+ // 控制台级别选择器
650
+ const consoleLevel = ref(ConsoleLevel.NORMAL)
651
+
652
+ watch(consoleLevel, (level) => {
653
+ cpuConsole.setLevel(level)
654
+ })
655
+
656
+ // 打印统计
657
+ function printStats() {
658
+ const stats = pipeline.getStats()
659
+ cpuConsole.printStats(stats)
660
+ }
661
+ </script>
662
+
663
+ <template>
664
+ <div>
665
+ <select v-model="consoleLevel">
666
+ <option :value="ConsoleLevel.SILENT">关闭</option>
667
+ <option :value="ConsoleLevel.MINIMAL">最小</option>
668
+ <option :value="ConsoleLevel.NORMAL">正常</option>
669
+ <option :value="ConsoleLevel.VERBOSE">详细</option>
670
+ <option :value="ConsoleLevel.DEBUG">调试</option>
671
+ </select>
672
+
673
+ <button @click="printStats">打印统计</button>
674
+ </div>
675
+ </template>
676
+ ```
677
+
678
+ ---
679
+
680
+ ## 📊 输出效果示例
681
+
682
+ ### 正常模式(NORMAL)
683
+
684
+ ```
685
+ 🎯 [12:34:56.123] task.update 指令创建
686
+
687
+ ✅ [12:34:56.248] task.update → 成功 125ms
688
+ 流水线阶段:
689
+ IF ████ 0ms
690
+ SCH ████ 0ms
691
+ EX ████████████████████ 123ms
692
+ WB ████ 2ms
693
+ ✓ 乐观更新
694
+ ```
695
+
696
+ ### 详细模式(VERBOSE)
697
+
698
+ ```
699
+ 🎯 [12:34:56.123] task.update 指令创建
700
+ { id: 'instr_xxx', correlationId: 'corr_xxx' }
701
+
702
+ 🔄 [12:34:56.124] 乐观更新已应用
703
+
704
+ ⏳ [12:34:56.124] 资源冲突,等待 10ms
705
+ { conflictingWith: ['instr_yyy'] }
706
+
707
+ ✅ [12:34:56.248] task.update → 成功 125ms
708
+ 流水线阶段:
709
+ IF ████ 0ms
710
+ SCH ████ 10ms
711
+ EX ████████████████████ 113ms
712
+ WB ████ 2ms
713
+ ✓ 乐观更新
714
+
715
+ 详细信息:
716
+ ┌────────────────┬─────────────────────┐
717
+ │ Instruction ID │ instr_xxx │
718
+ │ Correlation ID │ corr_xxx │
719
+ │ Type │ task.update │
720
+ │ Status │ COMMITTED │
721
+ └────────────────┴─────────────────────┘
722
+ ```
723
+
724
+ ### 失败模式(自动展开)
725
+
726
+ ```
727
+ ❌ [12:34:56.456] schedule.update → 失败 24ms
728
+ 原因: HTTP 500: database is locked
729
+
730
+ 流水线阶段:
731
+ IF ████ 0ms
732
+ SCH ████ 0ms
733
+ EX ████████████████ 22ms
734
+ WB ████ 2ms
735
+
736
+ ✓ 已回滚乐观更新
737
+
738
+ 💡 建议:
739
+ • 后端数据库锁定,检查写入许可是否正确获取
740
+ ```
741
+
742
+ ### 调试模式(DEBUG)
743
+
744
+ ```
745
+ 🎯 [12:34:56.123] task.update 指令创建
746
+ { id: 'instr_xxx', correlationId: 'corr_xxx', payload: { ... } }
747
+
748
+ 🔄 [12:34:56.124] 乐观更新已应用
749
+
750
+ 🌐 [12:34:56.125] PATCH /api/tasks/123
751
+ { correlationId: 'corr_xxx' }
752
+
753
+ ← [12:34:56.246] HTTP 200 (121ms)
754
+
755
+ ✅ [12:34:56.248] task.update → 成功 125ms
756
+ 流水线阶段: ...
757
+ 详细信息: ...
758
+ Payload: { task_id: 'xxx', updates: { ... } }
759
+ Result: { task: { ... }, side_effects: { ... } }
760
+ ```
761
+
762
+ ---
763
+
764
+ ## 🎛️ 配置选项
765
+
766
+ ### 级别说明
767
+
768
+ | 级别 | 用途 | 输出内容 |
769
+ |------|------|---------|
770
+ | SILENT | 完全关闭 | 无输出 |
771
+ | MINIMAL | 生产环境 | 只输出成功/失败 |
772
+ | NORMAL | 日常开发 | 输出关键阶段 |
773
+ | VERBOSE | 深度调试 | 输出所有细节 |
774
+ | DEBUG | 问题排查 | 输出 payload/result |
775
+
776
+ ### 过滤器
777
+
778
+ ```typescript
779
+ // 只看特定指令
780
+ cpuConsole.setFilter(['schedule.update', 'task.create'])
781
+
782
+ // 看所有指令
783
+ cpuConsole.setFilter([])
784
+ ```
785
+
786
+ ---
787
+
788
+ ## 🎨 最佳实践
789
+
790
+ 1. **开发环境用 VERBOSE**
791
+ - 能看到完整的执行流程
792
+ - 快速定位问题
793
+
794
+ 2. **生产环境用 MINIMAL**
795
+ - 减少控制台噪音
796
+ - 只在出错时查看
797
+
798
+ 3. **调试问题用 DEBUG**
799
+ - 看到完整的 payload 和 result
800
+ - 分析数据流动
801
+
802
+ 4. **使用过滤器聚焦**
803
+ - 开发某个功能时只看相关指令
804
+ - 减少干扰
805
+
806
+ 5. **配合 CPULogger 使用**
807
+ - Console:实时看执行
808
+ - Logger:事后深度分析
809
+
810
+ ---
811
+
812
+ ## 📦 完整架构
813
+
814
+ ```
815
+ ┌─────────────────────────────────────────┐
816
+ │ FrontCPU │
817
+ │ IF → SCH → EX → WB → INT │
818
+ └──────────┬─────────────┬─────────────────┘
819
+ │ │
820
+ ↓ ↓
821
+ ┌──────────────────┐ ┌──────────────────┐
822
+ │ CPUConsole │ │ CPULogger │
823
+ │ (实时打印) │ │ (审计分析) │
824
+ │ │ │ │
825
+ │ • 美观输出 │ │ • 结构化存储 │
826
+ │ • 分级控制 │ │ • 强大查询 │
827
+ │ • 即时反馈 │ │ • 性能分析 │
828
+ │ • 智能建议 │ │ • 离线审计 │
829
+ └──────────────────┘ └──────────────────┘
830
+ │ │
831
+ ↓ ↓
832
+ 开发调试 事后分析
833
+ 实时查看 性能监控
834
+ 快速定位 问题排查
835
+ ```
836
+
837
+ ---
838
+
839
+ **总结**:
840
+ - **CPUConsole**:开发者的"眼睛",实时看到指令执行
841
+ - **CPULogger**:系统的"黑匣子",记录所有细节用于分析
842
+ - 两者配合使用,覆盖"实时调试"和"事后分析"两个场景
843
+