29d2ffed8f
Replace overlap Pending flag with PendingRuns counter, match seed stats by job_id, align average duration with TimedRunCount, and tidy docs. Co-authored-by: Cursor <cursoragent@cursor.com>
2.9 KiB
2.9 KiB
GoSentry — Code Review (2026-06-29)
Версия на момент ревью: 0.11.2
Итог
| Критерий | Оценка |
|---|---|
| Архитектура | 9/10 |
| Сложность vs масштаб | 8/10 |
| Качество кода | 8/10 |
| Поддерживаемость | 8/10 |
| Логические ошибки | 9/10 (после исправлений) |
Проект зрелый и поддерживаемый для десктопного планировщика (~59 .go-файлов). Архитектура слоистая, core-логика хорошо протестирована.
Сильные стороны
- Single-writer
app.Serviceс явным locking contract - Разделение
domain.Job(durable) иdomain.JobRuntime(transient) - Event-driven UI без обратных вызовов в Fyne под lock
- Portable storage от
os.Executable() - Инъекция
runJobиscheduler.Clockв тестах - Подробная документация (
ARCHITECTURE.md, inline comments)
Найденные проблемы и статус исправлений
| # | Проблема | Серьёзность | Статус |
|---|---|---|---|
| 1 | Data race: store.Paths в executeRun без lock |
Высокая | Исправлено |
| 2 | Run стартует при ошибке SaveJobs |
Средняя | Исправлено |
| 3 | CRUD эмитит events при failed save | Средняя | Исправлено |
| 4 | Overlap queue — только один Pending |
Средняя | Исправлено (PendingRuns) |
| 5 | time.Now() vs scheduler clock в startRunLocked |
Низкая | Исправлено |
| 6 | Silent log write failures | Низкая | Исправлено |
| 7 | Невалидный per-job overlap_policy |
Низкая | Исправлено |
| 8 | Docs drift (YAML, RunNow/pause) | Низкая | Исправлено |
| 9 | StartOnly игнорировал cancel context |
Низкая | Исправлено |
| 10 | SeedStats коллизия sanitized имён |
Низкая | Исправлено (match по job_id) |
| 11 | AvgDurationMS seed vs live расходились |
Низкая | Исправлено (TimedRunCount) |
| 12 | Legacy ticket-ссылки в комментариях | Низкая | Исправлено |
Намеренное поведение (не баги)
RunNowразрешён при global pause и для disabled jobs- Sequential mode — FIFO по порядку в
jobs.json - Scheduler tick 1s — sub-second
@everyне поддерживается - Command timeout 30s — глобальный лимит
Рекомендации на будущее
- UI widget tests или smoke E2E
- Per-job command timeout в конфиге