chore: Java 26 + Gradle 9.7.0, all 20 deps updated, 1GB mem limit
- build.gradle: Gradle toolchain languageVersion 26 (auto-detects /usr/lib/jvm, no JAVA_HOME export needed), .java-version file for IDEs - gradle wrapper 9.3.1 -> 9.7.0, spotless 6.25->8.10.0, spotbugs 4.9.3->4.10.3 - Dockerfile: eclipse-temurin 26-jdk/jre-alpine + -Xmx512m G1GC StringDedup - docker-compose: bot mem_limit 1g - CI workflows: setup-java 26 - deps: jda 6.5.0, lavaplayer 2.2.7, logback 1.6.3, slf4j 2.0.18 (stable), caffeine 3.2.4, sqlite 3.53.2.1, hikaricp 7.1.0, okhttp 5.5.0, junit 5.13.4 + launcher 1.13.4, mockito 5.23.0, bytebuddy 1.18.12, checkstyle 13.10.0 (toolVersion), spotbugs plugin 6.4.8, jsoup 1.22.2 - 458 tests green, build green without JAVA_HOME export
This commit is contained in:
parent
78645e5727
commit
356fa9cb48
13 changed files with 344 additions and 36 deletions
88
TODO.md
88
TODO.md
|
|
@ -257,6 +257,94 @@ feature/economy/
|
|||
|
||||
---
|
||||
|
||||
### 🐾 Животные — зоо-викторины и картинки (public-apis) — 🟢 в работе
|
||||
|
||||
- [x] `feature/animals/AnimalApi` — клиент к 8 API (thecatapi, dog.ceo, randomfox, shibe.online, some-random-api, nekos.life, waifu.pics, catboys.com) с fallback-цепочкой
|
||||
- [x] `!catperson` / `!dogperson` / `!foxperson` — «Какой ты кот/пёс/лис»: % + роль + картинка (детерминировано ID)
|
||||
- [x] `!shibe` / `!birb` — картинки шиба-ину и птичек
|
||||
- [x] `!neko` / `!waifu` / `!catboy` — аниме-картинки (неко, вайфу, кошко-мальчик)
|
||||
- [ ] Факты: `!catfact` / `!dogfact` — факт + картинка (catfact.ninja, dog facts API)
|
||||
- [ ] `!joke` — анекдоты (jokeapi.dev, категории Any/Programming/Misc)
|
||||
- [ ] `!chuck` — цитаты Чака Норриса (api.chucknorris.io)
|
||||
- [ ] `!inspire` — мотивационные цитаты (zenquotes.io)
|
||||
- [ ] `!apod` — астрономическая картинка дня NASA (api.nasa.gov, бесплатный ключ)
|
||||
- [ ] `!iss` — где сейчас МКС (api.wheretheiss.at)
|
||||
- [ ] `!space` — кто сейчас в космосе (open-notify.org)
|
||||
- [ ] `!xkcd` — свежий стрип (xkcd.com/api)
|
||||
- [ ] `!meme <subreddit>` — расширить мем по сабреддиту
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Стабильность и скорость (2026-08-19, аудит сервера 185.176.94.38)
|
||||
|
||||
### Найдено в логах
|
||||
| # | Проблема | Статус |
|
||||
|---|----------|--------|
|
||||
| S01 | `LogEmbeds.ban`/`kick` — NPE `Value may not be null`, если бан/кик без причины (падал onSuccess-колбэк, терялся лог) | ✅ `reason != null ? reason : "Не указана"` |
|
||||
| S02 | `RatingService.getDeterministicValue` — гонка на общем `Random.setSeed()`: 2 пользователя одновременно → результаты «подменялись» | ✅ локальный `new Random(seed)` (thread-safe) |
|
||||
| S03 | Пул репортов на внешние API отсутствовал | ✅ `util/ApiRequestQueue` (пул 4, изоляция ответов) |
|
||||
| S04 | `Missed 2 heartbeats` — 1 раз, транзиентный (сеть), не повторяется | ➖ наблюдать |
|
||||
|
||||
### Что сделано
|
||||
- `util/ApiRequestQueue` — очередь исходящих запросов: каждый запрос выполняется изолированно, ответ не может подмешаться к соседнему, пул 4 не перегружает публичные API. Подключён в `AnimalApi` и `NekosLifeApi`, зарегистрирован в LifecycleModule (graceful shutdown)
|
||||
- `RatingService` — детерминированное значение теперь без общего `Random` (root cause «подмены ответов»)
|
||||
- `LogEmbeds.ban/kick` — дефолт причины «Не указана»
|
||||
|
||||
### Производительность (наблюдения)
|
||||
- Команды выполняются за 0–100 мс (virtual threads), CPU ~0.2%, RAM 186 МБ — узких мест нет
|
||||
- Основная задержка — внешние HTTP API (таймауты 10 с + retry с бэк-оффом); очередь ограничивает параллелизм до 4
|
||||
|
||||
### Оптимизации (2026-08-19)
|
||||
- [x] `AnimalApi` — Caffeine-кэш успешных URL (TTL 30 с): повторные `!neko`/`!catboy`/зоо-викторины отвечают мгновенно
|
||||
- [x] `MemeCommand` — HttpURLConnection (без таймаутов, мог висеть) → OkHttp 6с/8с
|
||||
- [ ] `Database` — включить `PRAGMA journal_mode = WAL` (сейчас нет — блокировки при конкурентной записи)
|
||||
- [ ] NekosLifeApi — таймауты/ретраи вынести в конфиг (10с → 8с, retry 3 → 2)
|
||||
- [ ] Негативный кэш неудачных запросов в AnimalApi (не долбить упавший API 30с)
|
||||
- [ ] Dockerfile — JVM флаги (`-Xmx512m -XX:+UseG1GC -XX:+UseStringDeduplication`)
|
||||
- [ ] Разобрать остальные `HttpURLConnection` на общий OkHttp-клиент
|
||||
|
||||
---
|
||||
|
||||
## 🚧 v2.5 — Java 25, рейтинги, память (2026-08-19)
|
||||
|
||||
### 1. Java 26 + Gradle 9.7.0
|
||||
- [x] `build.gradle`: `toolchain { languageVersion = 26 }` — Gradle сам находит JDK 26 (`/usr/lib/jvm/java-26-openjdk`), `export JAVA_HOME` больше не нужен
|
||||
- [x] `.java-version` (файл `26`) — для IDE/jenv/asdf
|
||||
- [x] `gradle/wrapper/gradle-wrapper.properties`: 9.3.1 → 9.7.0 (системный gradle 9.7.0 в `/usr/bin/gradle`)
|
||||
- [x] `Dockerfile`: `eclipse-temurin:21-jdk-alpine` → `26-jdk-alpine`, `21-jre-alpine` → `26-jre-alpine`
|
||||
- [x] Mockito 5.15.2 тянет ByteBuddy 1.14.x (не знает класс-файлы major 70) → добавить `byte-buddy:1.18.8` (уже в кэше, поддержка Java 26)
|
||||
- [x] CI workflows (ci/docker-publish/release): `java-version: "21"` → `"26"`
|
||||
- [x] Пересобрать локально + `spotlessApply` (Spotless 6.25→8.10.0, SpotBugs 4.9.3→4.10.3 для major 70; 458 тестов ✅)
|
||||
|
||||
### 1.1 Обновление зависимостей (2026-08-19, все 20)
|
||||
- [x] jda 6.4.2→6.5.0, lavaplayer 2.2.6→2.2.7, logback 1.5.18→1.6.3, caffeine 3.2.0→3.2.4
|
||||
- [x] sqlite 3.49.1.0→3.53.2.1, **hikaricp 6.3.0→7.1.0** (мажор, API совместим, тесты ✅), okhttp 5.4.0→5.5.0
|
||||
- [x] junit 5.12.1→5.13.4, junit-platform-launcher 1.12.1→1.13.4, mockito 5.15.2→5.23.0, bytebuddy 1.18.8→1.18.12
|
||||
- [x] **slf4j 2.1.0-alpha1 → 2.0.18** (стабильный вместо alpha)
|
||||
- [x] checkstyle 10.23.0→13.10.0 (toolVersion, требует Java 21+ ✓), spotbugsPlugin 6.1.7→6.4.8, jsoup 1.19.1→1.22.2
|
||||
- [x] gson 2.14.0, guice 7.0.0, lavalinkClient 3.4.0, dotenv 3.2.0, spotbugs 4.10.3 — актуальные, без изменений
|
||||
|
||||
### 2. `!generateratings` генерит только на 2 человек
|
||||
- [x] **Причина**: JDA `MemberCachePolicy.DEFAULT` кэширует только голосовых/owner/self + `ChunkingFilter` по умолчанию чанкует только гильдии ≥250 участников → `guild.getMembers()` = 2
|
||||
- [x] `core/JdaFactory.java`: `.setMemberCachePolicy(MemberCachePolicy.ALL)` + `.setMemberChunkingFilter(ChunkingFilter.ALL)`
|
||||
- [x] `GenerateRatingsCommand.java`: `guild.getMembers()` → `guild.loadMembers().get()` (подстраховка)
|
||||
|
||||
### 3. Команда топа/низа рейтингов
|
||||
- [x] `RatingsRepository`: `getTopRatings(guildId, type, limit)` + `getBottomRatings(...)` (ORDER BY value DESC/ASC LIMIT)
|
||||
- [x] Новая команда `feature/rating/commands/board/RatingBoardCommand` — флейворы `ratingstop`/`ratingbottom` (высшие/низшие), рендер `<@id> — value` без резолва участников, медали топ-3
|
||||
- [x] Зарегистрировать в `feature/utility/UtilityCommandRegistrar` (рядом с GenerateRatingsCommand)
|
||||
|
||||
### 4. Лимит памяти 1 ГБ
|
||||
- [x] `docker-compose.yml`: сервис `bot` → `mem_limit: 1g`
|
||||
- [x] `Dockerfile` ENTRYPOINT: JVM-флаги `-Xmx512m -XX:+UseG1GC -XX:+UseStringDeduplication`
|
||||
|
||||
### 5. Дальнейшие оптимизации (поиск)
|
||||
- [x] Изучено: Gradle 9.4+ нужен для Java 26 (9.7.0 ✓); Gradle 8.14.3 падает на major 69/70; JDA — `loadMembers()` требует GUILD_MEMBERS intent (у бота включён)
|
||||
- [ ] `Database`: `PRAGMA journal_mode = WAL`
|
||||
- [ ] NekosLifeApi: таймауты/ретраи в конфиг
|
||||
- [ ] Негативный кэш в AnimalApi
|
||||
- [ ] Свести все HttpURLConnection на OkHttp
|
||||
|
||||
---
|
||||
|
||||
## 🔴 Результаты аудита KISS/DRY/SOLID (2026-07-04)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue