Initial commit

This commit is contained in:
2026-06-30 15:14:37 +08:00
commit 15dab96872
311 changed files with 95639 additions and 0 deletions
+292
View File
@@ -0,0 +1,292 @@
# ConnPool 删除决策说明
**删除时间**: 2026-03-24
**状态**: ✅ 已完成
**决策依据**: YAGNI 原则(You Aren't Gonna Need It
---
## 📋 ConnPool 的设计目的
### **原始意图**
```go
// ConnPool 连接池 - 复用 net.Conn 以减少资源消耗
type ConnPool struct {
pools map[string][]net.Conn // key: 对端标识,value: 连接池
maxSize int // 最大连接数
// ...
}
```
**设计目标**:
1. ✅ 复用已建立的连接到同一对端
2. ✅ 避免每次都重新拨号(STUN/TURN/WS 等)
3. ✅ 减少资源消耗(每个连接有内存和 goroutine 开销)
---
## 🤔 是否需要保留?
### **现状分析**
#### **实际情况**
在 MeshRay 的 P2P 通信模型中:
```
Peer A ←→ Peer B
└── 只需要一个连接
```
**特点**:
- ✅ 每个 Peer 对之间只需要**一个活跃连接**
- ✅ 连接建立后持续使用,直到断开
- ✅ 不需要"池"的概念(不是 Web 服务器的高并发场景)
---
#### **ConnPool vs ConnectionManager**
| 方案 | ConnPool(连接池) | ConnectionManager(连接管理器) |
|------|-------------------|-------------------------------|
| **复杂度** | 高(102 行代码) | 低(~50 行代码) |
| **功能** | 连接池复用、大小限制、健康检查 | 简单映射管理、一对一连接 |
| **数据结构** | `map[string][]net.Conn` | `map[string]net.Conn` |
| **适用场景** | 高并发、多连接复用 | 一对一 P2P 连接 |
| **维护成本** | 高(需要管理池生命周期) | 低(简单的 CRUD) |
| **当前需求** | ❌ 不需要 | ✅ 正好满足 |
---
## 🎯 删除理由
### **1. 过度设计**
**ConnPool 的复杂逻辑**:
```go
// 需要管理:
- 连接池大小限制maxSize
- 连接的获取Get
- 连接的归还Put
- 连接的健康检查
- 过期连接的清理Clear
- 并发控制mutex
```
**但实际只需要**:
```go
// ConnectionManager 就够了:
- 保存连接Set
- 获取连接Get
- 关闭连接Close
```
---
### **2. 没有实际使用**
**审查结果**:
```bash
# 搜索整个项目
grep -r "ConnPool" .
grep -r "NewConnPool" .
grep -r "pool\.Get\|pool\.Put" .
```
**发现**:
-**没有任何地方使用 ConnPool**
- ❌ 只在文档中提到过
- ❌ 是"为未来可能的需求"提前写的代码
---
### **3. 违反 YAGNI 原则**
**YAGNI** = **You Aren't Gonna Need It**(你不会需要的)
**ConnPool 的问题**:
- ❌ 为不存在的"高并发场景"提前优化
- ❌ 增加了 102 行代码的维护成本
- ❌ 让架构变得更复杂
- ❷ 实际上完全用不到
---
### **4. 正确的做法**
`connection_manager.go` 中直接管理:
```go
type ConnectionManager struct {
mu sync.RWMutex
conns map[string]net.Conn // key: peerID
logger *zap.Logger
}
func (m *ConnectionManager) GetConnection(peerID string) net.Conn {
m.mu.RLock()
defer m.mu.RUnlock()
return m.conns[peerID]
}
func (m *ConnectionManager) SetConnection(peerID string, conn net.Conn) {
m.mu.Lock()
defer m.mu.Unlock()
// 关闭旧连接(如果有)
if oldConn, exists := m.conns[peerID]; exists {
oldConn.Close()
}
m.conns[peerID] = conn
}
func (m *ConnectionManager) CloseConnection(peerID string) {
m.mu.Lock()
defer m.mu.Unlock()
if conn, exists := m.conns[peerID]; exists {
conn.Close()
delete(m.conns, peerID)
}
}
```
**优点**:
- ✅ 简单直接 - 就是普通的 map 管理
- ✅ 每个 Peer 一个连接 - 符合实际需求
- ✅ 无需连接池 - 不需要复杂的复用逻辑
- ✅ 易于理解和维护
---
## 📊 如果未来真的需要 ConnPool
### **什么情况下需要?**
如果 MeshRay 未来支持:
1. **多路径传输** (Multipath Transport)
```
Peer A ←→ [Path 1] ←→ Peer B
↘ [Path 2] ↗
// 需要同时维护多个连接
```
2. **连接预热** (Connection Preheating)
```go
// 预先建立一批连接,等待分配
pool.Preheat(10) // 预建 10 个连接
```
3. **高并发场景** (High Concurrency)
```go
// 大量请求需要快速分配连接
for i := 0; i < 1000; i++ {
go func() {
conn := pool.Get("peer-x")
// ...
}()
}
```
**那么可以加 ConnPool**,但现在是**完全不需要**的。
---
## ✅ 删除决策
### **删除的文件**
```
core/pool/connpool.go (102 行)
```
### **删除的目录**
```
core/pool/ (空目录已自动清理)
```
### **影响评估**
- ✅ **无负面影响** - 没有任何地方使用它
- ✅ **代码更简洁** - 减少 102 行无用代码
- ✅ **架构更清晰** - 移除不必要的抽象层
- ✅ **维护更容易** - 少一个需要理解的组件
---
## 🎯 技术原则
### **本次决策遵循的原则**
1. **YAGNI 原则**
- ✅ You Aren't Gonna Need It
- ❌ 不要为不存在的需求写代码
2. **KISS 原则**
- ✅ Keep It Simple, Stupid
- ❌ 不要过度设计
3. **实事求是**
- ✅ 根据实际需求选择技术方案
- ❌ 不要模仿大厂的架构(场景不同)
4. **保持简洁**
- ✅ 简单往往就是最好的
- ❌ 复杂不等于好
---
## 📈 改进成果
### **代码减少**
| 项目 | 删除行数 | 删除文件 |
|------|----------|----------|
| ConnPool | 102 行 | 1 个文件 |
| pool 目录 | - | 1 个空目录 |
### **架构简化**
**删除前**:
```
core/
├── pool/
│ └── connpool.go # 连接池(未使用)
├── connection_manager.go # 连接管理器
```
**删除后**:
```
core/
├── connection_manager.go # 连接管理器(足够用了)
```
---
## 🎉 总结
### **核心改进**
-**删除过度设计** - ConnPool 对于 P2P 场景是多余的
-**回归本质** - 简单的 map 管理就够用了
-**代码简洁** - 减少 102 行无用代码
-**易于维护** - 架构更清晰
### **经验教训**
-**不要提前优化** - 除非证明需要
-**按需实现** - 根据实际需求写代码
-**保持简单** - 简单往往就是最好的
-**敢于删除** - 没用的代码就删掉
---
**删除完成时间**: 2026-03-24
**状态**: ✅ **已完成**
**评价**: ✅ **正确的决策**
*ConnPool 删除圆满完成!MeshRay 的架构更加简洁清晰!* 🎉