Homework/03 async grpc - #132
Open
invincible-summer wants to merge 3 commits into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
该 PR 为“03-async-grpc / 02-multithreading / 01-basic”作业补全实现:完善日志解析(Request/Internal)、多线程分析队列与 worker 逻辑,并打通 gRPC Agent/Client 端的调用链,同时补充作业问答报告与少量文档/忽略项调整。
Changes:
- 补全 LogParser 对 Request/Internal 日志的解析、Visitor 输出与 Accept 分发。
- 实现 LogAnalyzer 的 WorkQueue 与 LogFileAnalyzer 多线程 worker 执行与结果落盘。
- 完成 gRPC 端类型转换/visitor、AgentService/Session 逻辑与 RemoteCli/LocalCli 的交互命令;补充作业报告与文档表格格式。
Reviewed changes
Copilot reviewed 15 out of 18 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/RemoteCli/Program.cs | 实现远程 CLI:获取文件、发起分析、流式拉取分析结果 |
| src/LocalCli/Program.cs | 实现本地 CLI:列出文件、分析、查看结果 |
| src/LogParser/Parser/LineParser.cs | 支持解析 request/internal 两类日志事件 |
| src/LogParser/Visitors/KeyValueVisitor.cs | 为 Request/Internal 补全键值对导出 |
| src/LogParser/Models/LogEntries.cs | 为 Request/Internal 的 visitor 分发补全 Accept 实现 |
| src/LogAnalyzer/WorkQueue.cs | 实现线程安全工作队列(Enqueue/TryDequeue/CompleteAdding) |
| src/LogAnalyzer/LogFileAnalyzer.cs | 实现并行 worker 解析、过滤待解析文件、保存结果与 analyzing 状态 |
| src/LogAnalyzerRpc/GrpcTypeConverter.cs | 补全 severity/eventType 以及 Request/Internal log entry 的 gRPC ↔ 本地类型转换 |
| src/LogAnalyzerRpc/GrpcLogEntryVisitor.cs | 补全 Request/Internal 的 LogEntryMessage 构造 |
| src/LogAnalyzerAgent/Services/AgentService.cs | 将 gRPC service 方法转发到 session,并实现流式返回 |
| src/LogAnalyzerAgent/Applications/AgentSession.cs | 实现 ChangeDirectory/AnalyzeAll/AnalyzeFiles/GetAnalysisResult 的业务封装与错误处理 |
| docs/appendix/appendix-a-glossary.md | 调整术语表(表格)排版 |
| docs/03-async-grpc/report.md | 提交 03 作业问答报告内容 |
| docs/02-multithreading/report.md | 新增 02 作业问答报告内容 |
| docs/01-basic/report.md | 新增 01 作业问答报告内容 |
| .gitignore | 忽略 Obsidian / zcode 等本地目录 |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+211
to
+234
| while (await call.ResponseStream.MoveNext()) | ||
| { | ||
| var result = call.ResponseStream.Current; | ||
| switch (result.PayloadCase) { | ||
| case GetAnalysisResultResponse.PayloadOneofCase.Header: | ||
| Console.WriteLine($"Result of {result.Header.FileName}: State = {result.Header.State}"); | ||
| break; | ||
| case GetAnalysisResultResponse.PayloadOneofCase.LogEntry: | ||
| var entry = result.LogEntry; | ||
| switch (entry.EntryCase) | ||
| { | ||
| case LogEntryMessage.EntryOneofCase.CallLogEntry: | ||
| Console.WriteLine($" line {entry.CallLogEntry.LineNo}: call {entry.CallLogEntry.TargetService}"); | ||
| break; | ||
| case LogEntryMessage.EntryOneofCase.RequestLogEntry: | ||
| Console.WriteLine($" line {entry.RequestLogEntry.LineNo}: {entry.RequestLogEntry.Method} {entry.RequestLogEntry.Path} -> {entry.RequestLogEntry.StatusCode}"); | ||
| break; | ||
| case LogEntryMessage.EntryOneofCase.InternalLogEntry: | ||
| Console.WriteLine($" line {entry.InternalLogEntry.LineNo}: {entry.InternalLogEntry.ExceptionName}"); | ||
| break; | ||
| } | ||
| break; | ||
| } | ||
| } |
Comment on lines
+71
to
+83
| var exceptionspilt = internalMessage.Exception.IndexOf(": "); | ||
| if (exceptionspilt == -1) | ||
| { | ||
| throw new FormatException($"Invalid exception format: {internalMessage.Exception}"); | ||
| } | ||
| return new InternalLogEntry( | ||
| LineNo: logRecord.LineNo, | ||
| Timestamp: DateTimeOffset.Parse(logRecord.Timestamp), | ||
| PodName: logRecord.PodName, | ||
| Severity: ParseSeverity(internalMessage.Severity), | ||
| ExceptionName: internalMessage.Exception.Substring(0, exceptionspilt), | ||
| ExceptionMessage: internalMessage.Exception.Substring(exceptionspilt + 2) | ||
| ); |
| @@ -0,0 +1,22 @@ | |||
| ![[Pasted image 20260830144545.png]]![[Pasted image 20260830144609.png]] | |||
Comment on lines
+85
to
+93
| bool success = _analyzer.ChangeDirectory(request.DirectoryPath); | ||
| response.Status = success | ||
| ? CreateNoErrorOperationStatus() | ||
| : new OperationStatusMessage() | ||
| { | ||
| Success = false, | ||
| Code = AgentErrorCode.DirectoryNotFound, | ||
| Message = $"Invalid directory path: {request.DirectoryPath}.", | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
暑培:队式作业提交
基本信息
提交说明
03-async-grpc作业提交通道 #34