Add IPC backoff/retries and safer disposal

Introduce exponential backoff, jitter and retry logic across IPC components to improve robustness and avoid tight retry loops; make disposal idempotent and add connection guards. Key changes:
- LauncherCoordinatorIpcServer / LauncherIpcServer: add backoff constants, ComputeBackoff(), consecutive error tracking and delayed retries with jitter.
- LanMountainDesktopIpcClient / LauncherIpcClient: add connect retry loops, timeouts, delayed retries, improved error logging, and use ArrayPool for buffered async writes; ensure proper cleanup on failures.
- PublicIpcHostService: add disposed flag, guard OnPeerConnected and Dispose, and clear connected peers on dispose.
- Add many auto-generated commit analysis docs under docs/auto_commit_md and new scripts for analyzing/generating commit docs.
These changes aim to make IPC connection handling more resilient and resource-safe.
This commit is contained in:
lincube
2026-05-07 21:39:21 +08:00
parent 84caca02bf
commit d8f75e86be
159 changed files with 8809 additions and 31 deletions

View File

@@ -0,0 +1,389 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
解析 Git HEAD 日志文件并生成 Markdown 提交分析报告
"""
import re
import os
from datetime import datetime, timezone, timedelta
from pathlib import Path
def parse_head_log(log_content):
"""
解析 HEAD 日志内容,提取所有 commit 类型的提交
格式old_hash new_hash author_name <author_email> timestamp timezone\taction: message
"""
commits = []
# 匹配 commit 类型的行(包括 commit, commit (merge) 等)
# 注意message 部分可能包含中文,使用 .* 匹配
pattern = r'^([a-f0-9]{40}) ([a-f0-9]{40}) (.+) <([^>]+)> (\d+) ([+-]\d{4})\tcommit.*?: (.+)$'
for line in log_content.strip().split('\n'):
line = line.strip()
if not line:
continue
match = re.match(pattern, line)
if match:
old_hash, new_hash, author_name, author_email, timestamp, tz_offset, message = match.groups()
# 解析时间戳
ts = int(timestamp)
# 解析时区偏移
tz_hours = int(tz_offset[:3])
tz_mins = int(tz_offset[0] + tz_offset[3:5])
tz = timezone(timedelta(hours=tz_hours, minutes=tz_mins))
dt = datetime.fromtimestamp(ts, tz)
commits.append({
'old_hash': old_hash,
'new_hash': new_hash,
'short_hash': new_hash[:7],
'author_name': author_name,
'author_email': author_email,
'timestamp': ts,
'datetime': dt,
'date_str': dt.strftime('%Y-%m-%d'),
'time_str': dt.strftime('%H:%M:%S'),
'timezone': tz_offset,
'message': message.strip()
})
return commits
def analyze_commit_type(message):
"""
分析提交类型
支持的类型:
- feat: 新功能
- fix: 修复
- docs: 文档
- style: 格式
- refactor: 重构
- perf: 性能优化
- test: 测试
- chore: 构建/工具
- ci: CI/CD
- revert: 回滚
- change/changed: 变更
- remove/removed: 移除
"""
message_lower = message.lower()
# 定义类型映射
type_patterns = [
(r'^feat[.:\s]', 'feat', '新功能 (Feature)', '添加新功能或特性'),
(r'^fix[.:\s]', 'fix', '修复 (Bug Fix)', '修复问题或缺陷'),
(r'^docs[.:\s]', 'docs', '文档 (Documentation)', '文档更新'),
(r'^style[.:\s]', 'style', '格式 (Style)', '代码格式调整'),
(r'^refactor[.:\s]', 'refactor', '重构 (Refactor)', '代码重构'),
(r'^perf[.:\s]', 'perf', '性能优化 (Performance)', '性能改进'),
(r'^test[.:\s]', 'test', '测试 (Test)', '测试相关'),
(r'^chore[.:\s]', 'chore', '构建/工具 (Chore)', '构建流程或工具更新'),
(r'^ci[.:\s]', 'ci', 'CI/CD', '持续集成/部署'),
(r'^revert[.:\s]', 'revert', '回滚 (Revert)', '撤销之前的提交'),
(r'^change[d]?[.:\s]', 'change', '变更 (Change)', '功能或行为变更'),
(r'^remove[d]?[.:\s]', 'remove', '移除 (Remove)', '删除代码或功能'),
(r'^update[.:\s]', 'update', '更新 (Update)', '更新依赖或配置'),
(r'^add[.:\s]', 'add', '添加 (Add)', '添加新内容'),
(r'^introduce[.:\s]', 'introduce', '引入 (Introduce)', '引入新模块或概念'),
(r'^support[.:\s]', 'support', '支持 (Support)', '增加支持'),
(r'^migrate[.:\s]', 'migrate', '迁移 (Migrate)', '迁移或升级'),
(r'^bump[.:\s]', 'bump', '版本升级 (Bump)', '依赖版本升级'),
(r'^enable[.:\s]', 'enable', '启用 (Enable)', '启用功能'),
(r'^use[.:\s]', 'use', '使用 (Use)', '使用某技术或方法'),
(r'^make[.:\s]', 'make', '调整 (Make)', '调整实现'),
(r'^lock[.:\s]', 'lock', '锁定 (Lock)', '锁定特定行为'),
(r'^stamp[.:\s]', 'stamp', '标记 (Stamp)', '版本标记'),
(r'^harden[.:\s]', 'harden', '加固 (Harden)', '安全性/稳定性加固'),
(r'^resolve[.:\s]', 'resolve', '解决 (Resolve)', '解决问题'),
(r'^simplify[.:\s]', 'simplify', '简化 (Simplify)', '简化实现'),
(r'^move[.:\s]', 'move', '移动 (Move)', '文件或代码移动'),
(r'^rebuild[.:\s]', 'rebuild', '重建 (Rebuild)', '重建系统或流程'),
(r'^refresh[.:\s]', 'refresh', '刷新 (Refresh)', '刷新内容'),
(r'^normalize[.:\s]', 'normalize', '规范化 (Normalize)', '规范化处理'),
(r'^redesign[.:\s]', 'redesign', '重新设计 (Redesign)', 'UI/架构重新设计'),
]
for pattern, code, name, description in type_patterns:
if re.match(pattern, message_lower):
return {
'code': code,
'name': name,
'description': description
}
# 版本号提交(如 0.7.9.1, 0.8.0 等)
if re.match(r'^\d+\.\d+', message):
return {
'code': 'release',
'name': '版本发布 (Release)',
'description': '版本号更新或发布'
}
# 默认类型
return {
'code': 'other',
'name': '其他 (Other)',
'description': '其他类型的提交'
}
def generate_commit_markdown(commit):
"""为单个提交生成 Markdown 文档"""
commit_type = analyze_commit_type(commit['message'])
# 提取提交摘要第一行或前50个字符
summary = commit['message'].split('\n')[0][:100]
# 生成分析内容
md_content = f"""# 提交分析报告
## 1. 提交基本信息
| 属性 | 值 |
|------|-----|
| **完整哈希** | `{commit['new_hash']}` |
| **短哈希** | `{commit['short_hash']}` |
| **作者** | {commit['author_name']} <{commit['author_email']}> |
| **提交日期** | {commit['date_str']} |
| **提交时间** | {commit['time_str']} |
| **时区** | {commit['timezone']} |
| **父提交** | `{commit['old_hash']}` |
## 2. 提交信息摘要
```
{commit['message']}
```
**摘要**: {summary}
## 3. 变更类型分析
| 属性 | 值 |
|------|-----|
| **类型代码** | `{commit_type['code']}` |
| **类型名称** | {commit_type['name']} |
| **类型说明** | {commit_type['description']} |
## 4. 提交内容解读
"""
# 根据提交类型添加解读内容
if commit_type['code'] == 'feat':
md_content += f"""
这是一个**新功能**提交,引入了新的功能或特性。
**可能涉及的变更**:
- 新增功能模块或组件
- 新增 API 接口
- 新增用户界面元素
- 新增配置选项
**建议关注**:
- 新功能的实现方式
- 是否包含相应的测试用例
- 文档是否同步更新
"""
elif commit_type['code'] == 'fix':
md_content += f"""
这是一个**问题修复**提交,修复了系统中的某个问题或缺陷。
**可能涉及的变更**:
- 修复程序错误 (Bug)
- 修复 UI 显示问题
- 修复性能问题
- 修复兼容性问题
**建议关注**:
- 修复的问题描述
- 修复方案是否合理
- 是否引入了回归风险
"""
elif commit_type['code'] == 'docs':
md_content += f"""
这是一个**文档更新**提交,更新了项目文档。
**可能涉及的变更**:
- README 更新
- API 文档更新
- 注释完善
- 新增文档文件
**建议关注**:
- 文档内容准确性
- 文档格式规范性
"""
elif commit_type['code'] == 'refactor':
md_content += f"""
这是一个**代码重构**提交,对代码进行了重构优化。
**可能涉及的变更**:
- 代码结构优化
- 提取公共方法
- 重命名变量/类
- 消除重复代码
**建议关注**:
- 重构是否保持功能一致性
- 代码可读性是否提升
"""
elif commit_type['code'] == 'ci':
md_content += f"""
这是一个**CI/CD**提交,更新了持续集成/部署配置。
**可能涉及的变更**:
- GitHub Actions 工作流更新
- 构建脚本调整
- 发布流程优化
- 自动化测试配置
**建议关注**:
- CI 流程是否正常执行
- 部署流程是否受影响
"""
elif commit_type['code'] == 'release':
md_content += f"""
这是一个**版本发布**提交,标记了版本号更新。
**版本号**: {commit['message']}
**可能涉及的变更**:
- 版本号更新
- 发布打包
- 变更日志更新
- 标签创建
**建议关注**:
- 版本号是否符合语义化版本规范
- 变更日志是否完整
"""
elif commit_type['code'] == 'chore':
md_content += f"""
这是一个**构建/工具**提交,更新了构建流程或开发工具。
**可能涉及的变更**:
- 依赖包更新
- 构建配置调整
- 开发工具配置
- 脚本文件更新
**建议关注**:
- 构建是否正常
- 依赖兼容性
"""
elif commit_type['code'] == 'change':
md_content += f"""
这是一个**功能变更**提交,修改了现有功能的行为或实现。
**可能涉及的变更**:
- 功能行为调整
- 配置项变更
- 接口变更
- 默认值修改
**建议关注**:
- 变更是否向后兼容
- 是否需要更新文档
"""
else:
md_content += f"""
这是一个**{commit_type['name']}**提交。
**提交内容**:
{commit['message']}
**建议**:
- 查看具体代码变更以了解详细内容
- 结合项目上下文理解提交意图
"""
# 添加页脚
md_content += f"""
---
*此报告由自动提交分析工具生成*
*生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*
"""
return md_content
def main():
"""主函数"""
# 项目根目录
repo_root = Path('d:/github/LanMountainDesktop')
# 读取 HEAD 日志文件
head_log_path = repo_root / '.git' / 'logs' / 'HEAD'
output_dir = repo_root / 'docs' / 'auto_commit_md'
print(f"读取日志文件: {head_log_path}")
if not head_log_path.exists():
print(f"错误: 日志文件不存在: {head_log_path}")
return
with open(head_log_path, 'r', encoding='utf-8') as f:
log_content = f.read()
# 解析提交记录
commits = parse_head_log(log_content)
print(f"解析到 {len(commits)} 个 commit 类型提交")
# 确保输出目录存在
output_dir.mkdir(parents=True, exist_ok=True)
# 统计信息
generated_count = 0
skipped_count = 0
error_count = 0
# 为每个提交生成 Markdown 文件
for commit in commits:
# 文件名格式: YYYYMMDD_<short_hash>.md
filename = f"{commit['date_str'].replace('-', '')}_{commit['short_hash']}.md"
filepath = output_dir / filename
# 如果文件已存在,跳过
if filepath.exists():
print(f"跳过 (已存在): {filename}")
skipped_count += 1
continue
try:
# 生成 Markdown 内容
md_content = generate_commit_markdown(commit)
# 写入文件
with open(filepath, 'w', encoding='utf-8') as f:
f.write(md_content)
print(f"生成: {filename} - {commit['message'][:50]}")
generated_count += 1
except Exception as e:
print(f"错误: 生成 {filename} 失败: {e}")
error_count += 1
# 打印统计信息
print("\n" + "="*50)
print("生成完成!")
print(f" - 新生成: {generated_count} 个文件")
print(f" - 已跳过: {skipped_count} 个文件")
print(f" - 错误: {error_count} 个文件")
print(f" - 总计: {len(commits)} 个提交")
print(f"\n输出目录: {output_dir}")
if __name__ == '__main__':
main()