use cline and prepare to test the project for further development
Some checks failed
build container / build-container (push) Has been cancelled
Some checks failed
build container / build-container (push) Has been cancelled
This commit is contained in:
121
.clinerules
Normal file
121
.clinerules
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
# Project
|
||||||
|
|
||||||
|
## User Language
|
||||||
|
|
||||||
|
Simplified Chinese
|
||||||
|
|
||||||
|
# Cline's Memory Bank
|
||||||
|
|
||||||
|
I am Cline, an expert software engineer with a unique characteristic: my memory resets completely between sessions. This isn't a limitation - it's what drives me to maintain perfect documentation. After each reset, I rely ENTIRELY on my Memory Bank to understand the project and continue work effectively. I MUST read ALL memory bank files at the start of EVERY task - this is not optional.
|
||||||
|
|
||||||
|
## Memory Bank Structure
|
||||||
|
|
||||||
|
The Memory Bank consists of core files and optional context files, all in Markdown format. Files build upon each other in a clear hierarchy:
|
||||||
|
|
||||||
|
flowchart TD
|
||||||
|
PB[projectbrief.md] --> PC[productContext.md]
|
||||||
|
PB --> SP[systemPatterns.md]
|
||||||
|
PB --> TC[techContext.md]
|
||||||
|
|
||||||
|
PC --> AC[activeContext.md]
|
||||||
|
SP --> AC
|
||||||
|
TC --> AC
|
||||||
|
|
||||||
|
AC --> P[progress.md]
|
||||||
|
|
||||||
|
### Core Files (Required)
|
||||||
|
1. `projectbrief.md`
|
||||||
|
- Foundation document that shapes all other files
|
||||||
|
- Created at project start if it doesn't exist
|
||||||
|
- Defines core requirements and goals
|
||||||
|
- Source of truth for project scope
|
||||||
|
|
||||||
|
2. `productContext.md`
|
||||||
|
- Why this project exists
|
||||||
|
- Problems it solves
|
||||||
|
- How it should work
|
||||||
|
- User experience goals
|
||||||
|
|
||||||
|
3. `activeContext.md`
|
||||||
|
- Current work focus
|
||||||
|
- Recent changes
|
||||||
|
- Next steps
|
||||||
|
- Active decisions and considerations
|
||||||
|
- Important patterns and preferences
|
||||||
|
- Learnings and project insights
|
||||||
|
|
||||||
|
4. `systemPatterns.md`
|
||||||
|
- System architecture
|
||||||
|
- Key technical decisions
|
||||||
|
- Design patterns in use
|
||||||
|
- Component relationships
|
||||||
|
- Critical implementation paths
|
||||||
|
|
||||||
|
5. `techContext.md`
|
||||||
|
- Technologies used
|
||||||
|
- Development setup
|
||||||
|
- Technical constraints
|
||||||
|
- Dependencies
|
||||||
|
- Tool usage patterns
|
||||||
|
|
||||||
|
6. `progress.md`
|
||||||
|
- What works
|
||||||
|
- What's left to build
|
||||||
|
- Current status
|
||||||
|
- Known issues
|
||||||
|
- Evolution of project decisions
|
||||||
|
|
||||||
|
### Additional Context
|
||||||
|
Create additional files/folders within memory-bank/ when they help organize:
|
||||||
|
- Complex feature documentation
|
||||||
|
- Integration specifications
|
||||||
|
- API documentation
|
||||||
|
- Testing strategies
|
||||||
|
- Deployment procedures
|
||||||
|
|
||||||
|
## Core Workflows
|
||||||
|
|
||||||
|
### Plan Mode
|
||||||
|
flowchart TD
|
||||||
|
Start[Start] --> ReadFiles[Read Memory Bank]
|
||||||
|
ReadFiles --> CheckFiles{Files Complete?}
|
||||||
|
|
||||||
|
CheckFiles -->|No| Plan[Create Plan]
|
||||||
|
Plan --> Document[Document in Chat]
|
||||||
|
|
||||||
|
CheckFiles -->|Yes| Verify[Verify Context]
|
||||||
|
Verify --> Strategy[Develop Strategy]
|
||||||
|
Strategy --> Present[Present Approach]
|
||||||
|
|
||||||
|
### Act Mode
|
||||||
|
flowchart TD
|
||||||
|
Start[Start] --> Context[Check Memory Bank]
|
||||||
|
Context --> Update[Update Documentation]
|
||||||
|
Update --> Execute[Execute Task]
|
||||||
|
Execute --> Document[Document Changes]
|
||||||
|
|
||||||
|
## Documentation Updates
|
||||||
|
|
||||||
|
Memory Bank updates occur when:
|
||||||
|
1. Discovering new project patterns
|
||||||
|
2. After implementing significant changes
|
||||||
|
3. When user requests with **update memory bank** (MUST review ALL files)
|
||||||
|
4. When context needs clarification
|
||||||
|
|
||||||
|
flowchart TD
|
||||||
|
Start[Update Process]
|
||||||
|
|
||||||
|
subgraph Process
|
||||||
|
P1[Review ALL Files]
|
||||||
|
P2[Document Current State]
|
||||||
|
P3[Clarify Next Steps]
|
||||||
|
P4[Document Insights & Patterns]
|
||||||
|
|
||||||
|
P1 --> P2 --> P3 --> P4
|
||||||
|
end
|
||||||
|
|
||||||
|
Start --> Process
|
||||||
|
|
||||||
|
Note: When triggered by **update memory bank**, I MUST review every memory bank file, even if some don't require updates. Focus particularly on activeContext.md and progress.md as they track current state.
|
||||||
|
|
||||||
|
REMEMBER: After every memory reset, I begin completely fresh. The Memory Bank is my only link to previous work. It must be maintained with precision and clarity, as my effectiveness depends entirely on its accuracy.
|
26
memory-bank/activeContext.md
Normal file
26
memory-bank/activeContext.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# 当前工作重点
|
||||||
|
|
||||||
|
当前的主要任务是熟悉并理解现有的 `cache-proxy` 项目。这包括分析其代码结构、核心算法和设计模式。
|
||||||
|
|
||||||
|
## 近期变更
|
||||||
|
|
||||||
|
- **初始化 Memory Bank**: 创建了 Memory Bank 的核心文档,包括:
|
||||||
|
- `projectbrief.md`
|
||||||
|
- `productContext.md`
|
||||||
|
- `systemPatterns.md`
|
||||||
|
- `techContext.md`
|
||||||
|
- `activeContext.md`
|
||||||
|
- `progress.md`
|
||||||
|
|
||||||
|
## 后续步骤
|
||||||
|
|
||||||
|
1. **验证理解**: 与项目所有者沟通,确认对项目的设计和功能的理解是否准确。
|
||||||
|
2. **确定开发方向**: 明确项目当前是否存在需要修复的 bug、需要优化的性能瓶颈或需要开发的新功能。
|
||||||
|
3. **完善文档**: 根据后续的开发工作,持续更新和完善 Memory Bank 中的文档。
|
||||||
|
|
||||||
|
## 重要模式与偏好
|
||||||
|
|
||||||
|
- **代码风格**: 遵循 Go 社区的最佳实践,代码清晰、简洁,并有适当的注释。
|
||||||
|
- **并发编程**: 倾向于使用 Go 的原生并发原语(goroutine 和 channel)来解决并发问题。
|
||||||
|
- **配置驱动**: 核心逻辑应与配置分离,使得项目可以通过修改配置文件来适应不同的使用场景,而无需修改代码。
|
||||||
|
- **文档驱动**: 所有重要的设计决策、架构变更和功能实现都应在 Memory Bank 中有相应的记录。
|
26
memory-bank/productContext.md
Normal file
26
memory-bank/productContext.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# 产品背景
|
||||||
|
|
||||||
|
在许多场景下,用户需要从软件镜像站、文件服务器或其他资源站点下载文件。然而,由于网络波动、服务器负载或地理位置等原因,单个服务器的下载速度和稳定性可能无法得到保证。
|
||||||
|
|
||||||
|
## 解决的问题
|
||||||
|
|
||||||
|
`cache-proxy` 旨在解决以下问题:
|
||||||
|
|
||||||
|
1. **单点故障**: 当用户依赖的唯一镜像服务器宕机或无法访问时,下载会中断。
|
||||||
|
2. **网络速度不佳**: 用户可能没有连接到最快的可用服务器,导致下载时间过长。
|
||||||
|
3. **重复下载**: 多个用户或同一个用户多次下载相同的文件时,会产生不必要的网络流量,增加了服务器的负载。
|
||||||
|
|
||||||
|
## 工作原理
|
||||||
|
|
||||||
|
`cache-proxy` 通过在用户和多个上游服务器之间引入一个代理层来解决这些问题。
|
||||||
|
|
||||||
|
- 当收到一个文件请求时,它会并发地向所有配置的上游服务器请求该文件。
|
||||||
|
- 它会选择第一个返回成功响应的上游服务器,并将数据流式传输给用户。
|
||||||
|
- 同时,它会将文件缓存到本地磁盘。
|
||||||
|
- 对于后续的相同文件请求,如果缓存未过期,它将直接从本地提供文件,极大地提高了响应速度并减少了网络流量。
|
||||||
|
|
||||||
|
## 用户体验目标
|
||||||
|
|
||||||
|
- **无缝集成**: 用户只需将下载地址指向 `cache-proxy` 即可,无需关心后端的复杂性。
|
||||||
|
- **更快的下载**: 通过竞争机制选择最快的源,用户总能获得最佳的下载体验。
|
||||||
|
- **更高的可用性**: 即使部分上游服务器出现问题,只要有一个可用,服务就不会中断。
|
36
memory-bank/progress.md
Normal file
36
memory-bank/progress.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# 项目进展
|
||||||
|
|
||||||
|
这是一个已完成的 `cache-proxy` 项目的初始状态。核心功能已经实现并可以工作。
|
||||||
|
|
||||||
|
## 已完成的功能
|
||||||
|
|
||||||
|
- **核心代理逻辑**:
|
||||||
|
- 从 `config.yaml` 加载配置。
|
||||||
|
- 启动 HTTP 服务器并监听请求。
|
||||||
|
- 根据请求路径检查本地缓存。
|
||||||
|
- **并发上游请求**:
|
||||||
|
- 能够并发地向上游服务器发起请求。
|
||||||
|
- 能够正确地选择最快响应的服务器。
|
||||||
|
- 能够在选择一个服务器后取消其他请求。
|
||||||
|
- **缓存管理**:
|
||||||
|
- 能够将下载的文件缓存到本地磁盘。
|
||||||
|
- 支持基于时间的缓存刷新策略。
|
||||||
|
- 支持通过 `If-Modified-Since` 请求头来减少不必要的数据传输。
|
||||||
|
- **并发请求处理**:
|
||||||
|
- 能够正确处理对同一文件的多个并发请求,确保只下载一次。
|
||||||
|
- **加速下载**:
|
||||||
|
- 支持通过 `X-Sendfile` / `X-Accel-Redirect` 头将文件发送委托给前端服务器(如 Nginx)。
|
||||||
|
|
||||||
|
## 待办事项
|
||||||
|
|
||||||
|
- **功能增强**:
|
||||||
|
- 目前只支持本地文件存储,未来可以考虑增加对其他存储后端(如 S3、Redis)的支持。
|
||||||
|
- 增加更复杂的负载均衡策略,而不仅仅是“选择最快”。
|
||||||
|
- 增加更详细的监控和指标(如 Prometheus metrics)。
|
||||||
|
- **代码优化**:
|
||||||
|
- 对 `server.go` 中的一些复杂函数(如 `streamOnline`)进行重构,以提高可读性和可维护性。
|
||||||
|
- 增加更全面的单元测试和集成测试。
|
||||||
|
|
||||||
|
## 已知问题
|
||||||
|
|
||||||
|
- 在当前阶段,尚未发现明显的 bug。代码结构清晰,逻辑完整。
|
10
memory-bank/projectbrief.md
Normal file
10
memory-bank/projectbrief.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# 项目简介:Cache-Proxy
|
||||||
|
|
||||||
|
这是一个使用 Go 语言编写的高性能缓存代理服务器。其核心功能是接收客户端的请求,并将其转发到多个配置好的上游(Upstream)镜像服务器。它会并发地向上游服务器发起请求,并选择最快返回响应的服务器,将其结果返回给客户端,同时将结果缓存到本地,以便后续请求能够更快地得到响应。
|
||||||
|
|
||||||
|
## 核心需求
|
||||||
|
|
||||||
|
- **性能**: 必须能够快速地处理并发请求,并有效地利用缓存。
|
||||||
|
- **可靠性**: 当某个上游服务器不可用时,能够自动切换到其他可用的服务器。
|
||||||
|
- **可配置性**: 用户可以通过配置文件轻松地添加、删除和配置上游服务器、缓存策略以及其他行为。
|
||||||
|
- **透明性**: 对客户端来说,代理应该是透明的,客户端只需像访问普通服务器一样访问代理即可。
|
46
memory-bank/systemPatterns.md
Normal file
46
memory-bank/systemPatterns.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# 系统架构与设计模式
|
||||||
|
|
||||||
|
`cache-proxy` 的系统设计遵循了几个关键的模式和原则,以实现其高性能和高可用性的目标。
|
||||||
|
|
||||||
|
## 核心架构
|
||||||
|
|
||||||
|
系统可以分为三个主要部分:
|
||||||
|
|
||||||
|
1. **HTTP 服务器层**: 负责接收客户端请求,并使用中间件进行日志记录、错误恢复等通用处理。
|
||||||
|
2. **缓存处理层**: 检查请求的文件是否存在于本地缓存中,并根据缓存策略决定是直接提供缓存文件还是向上游请求。
|
||||||
|
3. **上游选择与下载层**: 这是系统的核心,负责并发地从多个上游服务器获取数据,并管理下载过程。
|
||||||
|
|
||||||
|
## 关键设计模式
|
||||||
|
|
||||||
|
### 1. 竞争式请求 (Racing Requests)
|
||||||
|
|
||||||
|
这是实现“选择最快”功能的核心模式。
|
||||||
|
|
||||||
|
- `fastesUpstream` 函数为每个上游服务器创建一个 goroutine。
|
||||||
|
- 所有 goroutine 并发地向上游服务器发送请求。
|
||||||
|
- 使用 `sync.Once` 来确保只有一个 goroutine 能够“胜出”并成为最终的数据源。
|
||||||
|
- 一旦有 goroutine 胜出,它会调用 `context.CancelFunc` 来通知所有其他 goroutine 停止工作,从而避免不必要的资源消耗。
|
||||||
|
|
||||||
|
### 2. 生产者-消费者模式 (Producer-Consumer)
|
||||||
|
|
||||||
|
在文件下载过程中,使用了生产者-消费者模式。
|
||||||
|
|
||||||
|
- **生产者**: `tryUpstream` 函数中的 goroutine 负责从上游服务器读取数据块(chunk),并将其放入一个 `chan Chunk` 中。
|
||||||
|
- **消费者**: `streamOnline` 函数中的代码从 `chan Chunk` 中读取数据,并执行两个操作:
|
||||||
|
1. 将数据写入 `bytes.Buffer`,供后续的请求者使用。
|
||||||
|
2. 将数据写入本地临时文件,用于持久化缓存。
|
||||||
|
|
||||||
|
### 3. 并发访问控制 (Mutex for Concurrent Access)
|
||||||
|
|
||||||
|
为了处理多个客户端同时请求同一个文件的情况,系统使用了 `sync.Mutex` 和一个 `map[string]*StreamObject`。
|
||||||
|
|
||||||
|
- 当第一个请求到达时,它会获得一个锁,并创建一个 `StreamObject` 来代表这个正在进行的下载任务。
|
||||||
|
- 后续对同一文件的请求会发现 `StreamObject` 已存在,它们不会再次向上游发起请求,而是会等待并从这个共享的 `StreamObject` 中读取数据。
|
||||||
|
- 下载完成后,`StreamObject` 会从 map 中移除。
|
||||||
|
|
||||||
|
### 4. 中间件 (Middleware)
|
||||||
|
|
||||||
|
项目使用了 Go 的标准 `http.Handler` 接口和中间件模式来构建请求处理链。
|
||||||
|
|
||||||
|
- `pkgs/middleware` 目录中定义了可重用的中间件,如 `httplog` 和 `recover`。
|
||||||
|
- 这种模式使得在不修改核心业务逻辑的情况下,可以轻松地添加或删除日志、认证、错误处理等功能。
|
26
memory-bank/techContext.md
Normal file
26
memory-bank/techContext.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# 技术栈与开发环境
|
||||||
|
|
||||||
|
## 核心技术
|
||||||
|
|
||||||
|
- **语言**: Go (Golang)
|
||||||
|
- **主要依赖**:
|
||||||
|
- `gopkg.in/yaml.v3`: 用于解析 `config.yaml` 配置文件。
|
||||||
|
- `log/slog`: Go 1.21+ 内置的结构化日志库。
|
||||||
|
- `net/http`: 用于构建 HTTP 服务器和客户端。
|
||||||
|
- `github.com/getsentry/sentry-go`: (可选)用于错误追踪。
|
||||||
|
|
||||||
|
## 开发与构建
|
||||||
|
|
||||||
|
- **依赖管理**: 使用 Go Modules (`go.mod`, `go.sum`) 进行依赖管理。
|
||||||
|
- **配置文件**: 项目的行为由 `config.yaml` 文件驱动。
|
||||||
|
- **容器化**:
|
||||||
|
- `Dockerfile`: 用于构建项目的 Docker 镜像。
|
||||||
|
- `compose.yaml`: 用于在开发环境中启动服务。
|
||||||
|
- `compose.release.yaml`: 用于在生产环境中部署服务。
|
||||||
|
|
||||||
|
## 关键技术点
|
||||||
|
|
||||||
|
- **并发模型**: 大量使用 goroutine 和 channel 来实现高并发。特别是 `fastesUpstream` 函数中的并发请求模式。
|
||||||
|
- **流式处理**: 通过 `io.Reader` 和 `io.Writer` 接口,数据以流的形式被处理,从未完全加载到内存中,这对于处理大文件至关重要。
|
||||||
|
- **错误处理**: 在 Go 的标准错误处理之上,项目在某些关键路径(如 `fastesUpstream`)中使用了 `context` 包来处理超时和取消操作。
|
||||||
|
- **结构化日志**: 使用 `slog` 库,可以输出结构化的、易于机器解析的日志,方便调试和监控。
|
Reference in New Issue
Block a user