387f252b9d
- Update module path from github.com/strix-project/strix to github.com/eduard256/Strix - Update all Go imports to use new repository path - Update documentation links in README.md and CHANGELOG.md - Update GitHub URLs in .goreleaser.yaml - Fix placeholder documentation URL in DATABASE_FORMAT.md - Remove old log files
186 lines
5.8 KiB
Markdown
186 lines
5.8 KiB
Markdown
# Результаты тестирования дедупликации потоков
|
||
|
||
## Запуск тестов
|
||
|
||
```bash
|
||
go test -v ./internal/camera/stream -run "Dedup|Worst|Multiple"
|
||
```
|
||
|
||
## ✅ Тесты выполнены успешно
|
||
|
||
Все тесты **PASS**, что означает, что они успешно **ДЕМОНСТРИРУЮТ ПРОБЛЕМУ** текущей системы дедупликации.
|
||
|
||
---
|
||
|
||
## 📊 Результаты
|
||
|
||
### Тест 1: HTTP Authentication Variants
|
||
|
||
**Проблема:** Один HTTP endpoint генерирует 4 разных URL
|
||
|
||
```
|
||
http://192.168.1.100/snapshot.jpg
|
||
http://admin:12345@192.168.1.100/snapshot.jpg
|
||
http://192.168.1.100/snapshot.jpg?pwd=12345&user=admin
|
||
http://admin:12345@192.168.1.100/snapshot.jpg?pwd=12345&user=admin
|
||
```
|
||
|
||
- **Реально уникальных:** 1 поток
|
||
- **Генерируется:** 4 URL
|
||
- **Потери:** 3 лишних теста (75%)
|
||
|
||
---
|
||
|
||
### Тест 2: HTTP with Placeholders
|
||
|
||
**Проблема:** URL с плейсхолдерами генерирует дубликаты
|
||
|
||
```
|
||
Entry: snapshot.cgi?user=[USERNAME]&pwd=[PASSWORD]
|
||
|
||
Generated:
|
||
http://192.168.1.100/snapshot.cgi?pwd=&user=
|
||
http://admin:12345@192.168.1.100/snapshot.cgi?pwd=&user=
|
||
http://192.168.1.100/snapshot.cgi?pwd=12345&user=admin
|
||
http://admin:12345@192.168.1.100/snapshot.cgi?pwd=12345&user=admin
|
||
```
|
||
|
||
- **Реально уникальных:** 1 поток
|
||
- **Генерируется:** 4 URL
|
||
- **Потери:** 3 лишних теста (75%)
|
||
|
||
---
|
||
|
||
### Тест 3: RTSP with/without Credentials
|
||
|
||
**Проблема:** RTSP генерирует 2 варианта одного потока
|
||
|
||
```
|
||
rtsp://admin:12345@192.168.1.100/live/main
|
||
rtsp://192.168.1.100/live/main
|
||
```
|
||
|
||
- **Реально уникальных:** 1 поток
|
||
- **Генерируется:** 2 URL
|
||
- **Потери:** 1 лишний тест (50%)
|
||
|
||
---
|
||
|
||
### Тест 4: Multiple Sources (Popular + Model)
|
||
|
||
**Проблема:** Разные источники генерируют одинаковые паттерны
|
||
|
||
```
|
||
Source 1 (Popular Patterns):
|
||
rtsp://admin:12345@192.168.1.100/Streaming/Channels/101
|
||
rtsp://192.168.1.100/Streaming/Channels/101
|
||
|
||
Source 2 (Model Patterns):
|
||
rtsp://admin:12345@192.168.1.100/Streaming/Channels/101
|
||
rtsp://192.168.1.100/Streaming/Channels/101
|
||
```
|
||
|
||
**Текущая дедупликация:**
|
||
- Детектирует: 2 точных совпадения (50%)
|
||
- НЕ детектирует: 1 семантический дубль
|
||
|
||
**Итого:**
|
||
- Total generated: 4 URL
|
||
- After current dedup: 2 URL
|
||
- Real unique: 1 поток
|
||
- **Эффективность: 50%** (должна быть 75%)
|
||
|
||
---
|
||
|
||
### Тест 5: Worst Case Scenario
|
||
|
||
**Проблема:** Один паттерн из 3 источников (Popular + Model + ONVIF)
|
||
|
||
```
|
||
Popular patterns generates: 4 URLs
|
||
Model patterns generates: 4 URLs
|
||
ONVIF returns: 1 URL
|
||
```
|
||
|
||
**После текущей дедупликации:** 4 URL остаются
|
||
|
||
```
|
||
http://192.168.1.100/snapshot.jpg
|
||
http://admin:12345@192.168.1.100/snapshot.jpg
|
||
http://192.168.1.100/snapshot.jpg?pwd=12345&user=admin
|
||
http://admin:12345@192.168.1.100/snapshot.jpg?pwd=12345&user=admin
|
||
```
|
||
|
||
**Canonical analysis:**
|
||
- Real unique streams: **1**
|
||
- URLs being tested: **4**
|
||
- **Waste: 3 unnecessary tests (75%)**
|
||
- **Time waste: ~6 seconds** (assuming 2s per test)
|
||
|
||
---
|
||
|
||
## 🔴 Критические выводы
|
||
|
||
### 1. Текущая система НЕ работает для семантических дубликатов
|
||
|
||
Простое сравнение строк `urlMap[url] = true` детектирует только **точные совпадения**.
|
||
|
||
### 2. Масштаб проблемы
|
||
|
||
| Сценарий | Генерируется | Реально | Потери |
|
||
|----------|--------------|---------|--------|
|
||
| HTTP auth variants | 4 | 1 | 75% |
|
||
| RTSP with/without creds | 2 | 1 | 50% |
|
||
| Multiple sources | 4 | 1 | 75% |
|
||
| Worst case | 4 | 1 | 75% |
|
||
|
||
**Среднее:** ~69% лишних тестов!
|
||
|
||
### 3. Реальные последствия
|
||
|
||
При типичном сканировании:
|
||
- **Генерируется:** ~190 URL
|
||
- **Реально уникальных:** ~80-95
|
||
- **Лишних тестов:** 95-110 (50%)
|
||
- **Потери времени:** 3-4 минуты
|
||
- **Лишняя нагрузка на камеру:** 100+ запросов
|
||
- **Плохой UX:** пользователь видит один поток 4 раза
|
||
|
||
---
|
||
|
||
## ✅ Решение
|
||
|
||
Тесты доказывают необходимость **канонической нормализации URL**.
|
||
|
||
См. файл `/tmp/dedup_solutions.md` для подробного описания решений.
|
||
|
||
### Рекомендуемый подход: Гибридный
|
||
|
||
1. **В Builder:** Уменьшить генерацию вариантов (с 4 до 2-3)
|
||
2. **В Scanner:** Добавить `CanonicalURL()` функцию
|
||
3. **Ожидаемый результат:** Дедупликация 99% вместо текущих 50%
|
||
|
||
---
|
||
|
||
## 📝 Следующие шаги
|
||
|
||
1. ✅ Написать тесты (done)
|
||
2. ⏳ Реализовать `normalizer.go` с `CanonicalURL()`
|
||
3. ⏳ Модифицировать `Builder.BuildURLsFromEntry()` - убрать лишние варианты
|
||
4. ⏳ Модифицировать `Scanner.collectStreams()` - использовать canonical map
|
||
5. ⏳ Добавить метрики дедупликации в логи
|
||
6. ⏳ Прогнать тесты заново и убедиться в улучшении
|
||
|
||
---
|
||
|
||
## 🎯 Ожидаемый результат
|
||
|
||
После внедрения решения:
|
||
|
||
```
|
||
Real unique streams: 1
|
||
URLs being tested: 1 ← вместо 4
|
||
Waste: 0 unnecessary tests (0%) ← вместо 75%
|
||
Deduplication effectiveness: 99% ← вместо 50%
|
||
```
|