docs: update TODO with global roadmap (engine, DHT, logs, UI, killer features)
This commit is contained in:
parent
7cf20e00c6
commit
02afe80d91
1 changed files with 38 additions and 117 deletions
155
TODO.md
155
TODO.md
|
|
@ -1,126 +1,47 @@
|
||||||
# ZTorrent — TODO & Контекст улучшений
|
# ZTORRENT — ROADMAP & TODO
|
||||||
|
|
||||||
> Цель: довести ztorrent до уровня qBittorrent по функциональности и скорости.
|
> **Глобальная цель:** Довести Ztorrent до продакшен-уровня (стандарты qBittorrent и выше), сохранив консольную эстетику.
|
||||||
> Ведётся автоматически — отражает актуальное состояние реализации.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Архитектура проекта
|
## 🚀 Глобальный план развития (Roadmap)
|
||||||
|
|
||||||
```
|
### 1. Движок уровня qBittorrent (Core Engine)
|
||||||
internal/
|
- [ ] **Оптимизация I/O:** Асинхронная запись на диск (mmap / AIO), чтобы не было фризов UI при скачивании на гигабитных скоростях.
|
||||||
torrent/
|
- [ ] **Продвинутый кэш:** Умное кэширование кусков в ОЗУ перед сбросом на диск.
|
||||||
engine.go — основной движок: загрузка торрента, воркеры, координация
|
- [ ] **Smart Ban / Anti-Leech:** Автоматический бан плохих пиров, защита от спам-хэшей и некорректных кусков.
|
||||||
peerwire.go — BitTorrent wire protocol: handshake, download piece, messages
|
- [ ] **Приоритизация файлов:** Возможность выбирать, какие файлы из раздачи качать первыми.
|
||||||
piecescheduler.go — выбор кусков (rarest-first), endgame mode
|
|
||||||
debug.go — debugf helper
|
### 2. Идеальный DHT
|
||||||
tracker/
|
- [ ] **BEP 44 (Arbitrary Data):** Хранение произвольных данных в DHT.
|
||||||
tracker.go — HTTP + UDP announce
|
- [ ] **Умный роутинг (Kademlia 2.0):** Динамическое поддержание "живых" нод в bucket'ах, пинги в фоне.
|
||||||
torrentfile/
|
- [ ] **IPv6 DHT:** Поддержка поиска пиров в IPv6 сетях.
|
||||||
torrentfile.go — парсинг .torrent (bencode)
|
- [ ] **Локальный поиск (LSD):** Поиск пиров в локальной сети (Local Service Discovery).
|
||||||
app/
|
|
||||||
controller.go — тонкая обёртка над Engine для UI
|
### 3. Умное логирование (Smart Logging)
|
||||||
ui/
|
- [ ] **Уровни логов (Levels):** Переход на структурированные логи (DEBUG, INFO, WARN, ERROR).
|
||||||
ui.go — Bubble Tea TUI (welcome, loading, dashboard)
|
- [ ] **Фильтрация логов в UI:** Возможность прямо в TUI отфильтровать логи по "DHT", "Peers", "Disk".
|
||||||
styles.go — цветовая палитра
|
- [ ] **Аналитика сессии:** Summary по итогам скачивания (сколько отброшено кусков, средняя скорость, топовые пиры).
|
||||||
```
|
|
||||||
|
### 4. Эргономика UI (UX Refactoring)
|
||||||
|
- [ ] **Интерактивные таблицы:** Возможность сортировки по столбцам (по скорости, проценту скачивания).
|
||||||
|
- [ ] **Просмотр файлов внутри торрента:** Древовидная структура (`tree view`) для многофайловых торрентов.
|
||||||
|
- [ ] **Настройки "на лету":** Вызов окна настроек (`Config`) прямо из UI (лимиты скорости, порты, пути).
|
||||||
|
- [ ] **Визуализация Swarm'а:** Красивая карта пиров или график скорости (ASCII Sparklines).
|
||||||
|
|
||||||
|
### 5. Killer-Features (Убийцы qBit)
|
||||||
|
- [ ] **Стриминг в плеер (VLC/mpv):** Скачивание торрента "на лету" (куски по порядку) с пробросом HTTP-стрима прямо в медиаплеер (нажал кнопку — фильм сразу открылся).
|
||||||
|
- [ ] **Интеграция с Telegram / Discord:** Уведомления об окончании загрузки прямо на телефон.
|
||||||
|
- [ ] **CLI Remote Control:** Возможность поднять Ztorrent как демона на сервере и управлять им через SSH/TUI удалённо по RPC.
|
||||||
|
- [ ] **Web-виджет (Read-Only):** Поднятие легковесного веб-сервера для просмотра статуса загрузок с телефона.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## P0 — Критичные ✅ ГОТОВО
|
## 🛠 Выполнено (Архив)
|
||||||
|
|
||||||
- [x] **Resume download** — `createOrOpenPartFile()` без O_TRUNC + SHA-1 верификация
|
- ✅ **Magnet-ссылки (BEP 9)** и метаданные.
|
||||||
- [x] **Keep-alive** — `keepaliveLoop()` горутина, 90с, `msgCancel=8`
|
- ✅ **Базовый DHT (BEP 5)** с непрерывным поиском.
|
||||||
- [x] **Endgame mode** — `pieceDone` broadcast + `SendCancel()` при дублировании
|
- ✅ **Мультитрекерность** (HTTP + UDP).
|
||||||
|
- ✅ **Resume Data / Endgame Mode / Keep-alive.**
|
||||||
## P1 — Производительность ✅ ГОТОВО
|
- ✅ **Журнал (History) и Логи (Session Logs).**
|
||||||
|
- ✅ **TUI интерфейс** с глобальными оверлеями (О программе, Журнал, Логи).
|
||||||
- [x] **Adaptive pipeline** — depth 4–64, пересчёт каждые 4 блока по RTT+BW
|
|
||||||
- [x] **IPv6 compact peers** — `parsePeers6()` в tracker.go
|
|
||||||
- [x] **Rate limiting** — `rateLimitedConn`, `SetDownloadLimit`/`SetUploadLimit`
|
|
||||||
- [x] **Bitmap resume data** — `.part.bitmap` JSON, `asyncSaveBitmap()` в heartbeat
|
|
||||||
|
|
||||||
## Баги ✅ ПОФИКШЕНО
|
|
||||||
|
|
||||||
- [x] **`announce` пустой** — BEP 12 fallback: берём первый URL из `announce-list`
|
|
||||||
> `torrentfile.go` → `primaryAnnounce` fallback в `Open()`
|
|
||||||
|
|
||||||
- [x] **`peerBackoff` O(n)** → O(1) через `peerIdx map[string]int`
|
|
||||||
> Добавлен `Engine.peerIdx`, `peerByKey()` helper
|
|
||||||
> Все peer-методы: `setPeerState`, `setPeerError`, `peerBackoff`, `recordPieceComplete`
|
|
||||||
|
|
||||||
- [x] **Скорость без EWMA** → сглаживание α=0.3 в `updateSpeedLocked()`
|
|
||||||
> `downloadSpeed = 0.3*sample + 0.7*prev`
|
|
||||||
|
|
||||||
- [x] **Reannounce блокирует heartbeat** → запускается в отдельной горутине
|
|
||||||
> `heartbeatTicker.C` → `go func() { refreshPeersFromTrackers() }()`
|
|
||||||
> Таймаут уменьшен с 20с до 15с
|
|
||||||
|
|
||||||
## Фича ✅ РЕАЛИЗОВАНО
|
|
||||||
|
|
||||||
- [x] **Incoming connections** — TCP listener на :6881
|
|
||||||
> `listenIncoming()` + `handleIncoming()` в engine.go
|
|
||||||
> Handshake верификация (info_hash), регистрация в `peerIdx`
|
|
||||||
> Входящие пиры подхватываются `startWorkers` на следующем heartbeat тике
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## P2 — Долгосрочные (не начато)
|
|
||||||
|
|
||||||
- [x] **DHT (BEP 5)** — Kademlia DHT для поиска пиров без трекера
|
|
||||||
> Новый пакет `internal/dht/` — реализовано!
|
|
||||||
|
|
||||||
- [x] **Магнет-ссылки (BEP 9)** — `magnet:?xt=...`, ut_metadata extension
|
|
||||||
> Новый пакет `internal/magnet/` — средняя сложность
|
|
||||||
|
|
||||||
- [x] **Seeding / upload (tit-for-tat)** — раздача после завершения
|
|
||||||
> `peerwire.go` → обработка `msgRequest`, отправка `msgPiece`
|
|
||||||
|
|
||||||
- [x] **PEX (BEP 11)** — Peer Exchange между пирами
|
|
||||||
> Extension handshake + `ut_pex` message
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Технические решения
|
|
||||||
|
|
||||||
### peerIdx — O(1) peer lookup
|
|
||||||
```
|
|
||||||
Engine.peers []PeerStatus // слайс со всеми пирами
|
|
||||||
Engine.peerIdx map[string]int // "host:port" → индекс в слайсе
|
|
||||||
|
|
||||||
buildPeerIdx(peers) // строится при LoadTorrent и reannounce
|
|
||||||
peerByKey(key) *PeerStatus // O(1) под e.mu
|
|
||||||
```
|
|
||||||
|
|
||||||
### EWMA сглаживание скорости
|
|
||||||
```
|
|
||||||
updateSpeedLocked():
|
|
||||||
sample = delta_bytes / elapsed_sec
|
|
||||||
speed = 0.3*sample + 0.7*prev_speed // α=0.3
|
|
||||||
```
|
|
||||||
|
|
||||||
### Incoming connections flow
|
|
||||||
```
|
|
||||||
runDownload()
|
|
||||||
└── go listenIncoming(ctx, tf)
|
|
||||||
└── net.Listen(":6881")
|
|
||||||
└── for { conn = Accept() → go handleIncoming(conn) }
|
|
||||||
├── ReadFull → verify wireProtocol + infoHash
|
|
||||||
├── Write reply handshake
|
|
||||||
└── register peer in peerIdx
|
|
||||||
→ подхватывается startWorkers на следующем heartbeat
|
|
||||||
```
|
|
||||||
|
|
||||||
### Resume flow
|
|
||||||
```
|
|
||||||
createOrOpenPartFile():
|
|
||||||
├── если .part существует + .bitmap → verifyPieces() (быстро)
|
|
||||||
├── если .part существует, нет bitmap → verifyAllPieces() (SHA-1 scan)
|
|
||||||
└── если .part нет → создаём новый, Truncate(size)
|
|
||||||
|
|
||||||
heartbeat:
|
|
||||||
asyncSaveBitmap() → .part.bitmap
|
|
||||||
|
|
||||||
завершение:
|
|
||||||
os.Remove(.part) + os.Remove(.part.bitmap)
|
|
||||||
```
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue