fix(music): add Lavalink health-check with auto-reconnect
- Add 30s scheduled health-check that detects unavailable nodes - Remove and re-add node when it becomes unavailable (fixes WS disconnect) - Log WebSocketClosedEvent for debugging connection drops
This commit is contained in:
parent
520dccbafe
commit
ad17cff40e
2 changed files with 54 additions and 4 deletions
|
|
@ -9,6 +9,7 @@ import dev.arbjerg.lavalink.client.event.ReadyEvent;
|
|||
import dev.arbjerg.lavalink.client.event.StatsEvent;
|
||||
import dev.arbjerg.lavalink.client.event.TrackEndEvent;
|
||||
import dev.arbjerg.lavalink.client.event.TrackStartEvent;
|
||||
import dev.arbjerg.lavalink.client.event.WebSocketClosedEvent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
|
@ -65,5 +66,18 @@ class LavalinkEventRouter {
|
|||
manager.getScheduler().onTrackEnd(event.getTrack(), event.getEndReason());
|
||||
}
|
||||
});
|
||||
|
||||
client
|
||||
.on(WebSocketClosedEvent.class)
|
||||
.subscribe(
|
||||
event ->
|
||||
LoggerDecorator.music(
|
||||
logger,
|
||||
"WebSocket закрыт: code="
|
||||
+ event.getCode()
|
||||
+ ", reason="
|
||||
+ event.getReason()
|
||||
+ ", byRemote="
|
||||
+ event.getByRemote()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ package creator.loki.feature.music.core;
|
|||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.LongConsumer;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
|
@ -27,6 +30,13 @@ public class LavalinkManager {
|
|||
private final BotConfig config;
|
||||
private final QueueRepository queueRepository;
|
||||
private volatile LongConsumer voiceDisconnectHandler;
|
||||
private final ScheduledExecutorService healthCheck =
|
||||
Executors.newSingleThreadScheduledExecutor(
|
||||
r -> {
|
||||
Thread t = new Thread(r, "lavalink-health-check");
|
||||
t.setDaemon(true);
|
||||
return t;
|
||||
});
|
||||
|
||||
@Inject
|
||||
public LavalinkManager(BotConfig config, QueueRepository queueRepository) {
|
||||
|
|
@ -46,6 +56,17 @@ public class LavalinkManager {
|
|||
|
||||
this.client = new LavalinkClient(Helpers.getUserIdFromToken(botToken));
|
||||
|
||||
addNode(lavalinkConfig);
|
||||
|
||||
new LavalinkEventRouter(client, musicManagers).register();
|
||||
|
||||
healthCheck.scheduleWithFixedDelay(this::checkNodeHealth, 30, 30, TimeUnit.SECONDS);
|
||||
|
||||
LoggerDecorator.music(
|
||||
logger, "LavalinkManager инициализирован, нода: " + lavalinkConfig.getWsUri());
|
||||
}
|
||||
|
||||
private void addNode(LavalinkConfig lavalinkConfig) {
|
||||
client.addNode(
|
||||
new NodeOptions.Builder()
|
||||
.setName("main")
|
||||
|
|
@ -53,11 +74,26 @@ public class LavalinkManager {
|
|||
.setPassword(lavalinkConfig.getPassword())
|
||||
.setHttpTimeout(30000L)
|
||||
.build());
|
||||
}
|
||||
|
||||
new LavalinkEventRouter(client, musicManagers).register();
|
||||
|
||||
LoggerDecorator.music(
|
||||
logger, "LavalinkManager инициализирован, нода: " + lavalinkConfig.getWsUri());
|
||||
private void checkNodeHealth() {
|
||||
try {
|
||||
var nodes = client.getNodes();
|
||||
if (nodes.isEmpty()) {
|
||||
logger.warn("Lavalink: нет нод, пересоздаю");
|
||||
addNode(config.getLavalinkConfig());
|
||||
return;
|
||||
}
|
||||
var node = nodes.get(0);
|
||||
if (!node.getAvailable()) {
|
||||
logger.warn("Lavalink нода '{}' недоступна, переподключаю", node.getName());
|
||||
client.removeNode(node);
|
||||
addNode(config.getLavalinkConfig());
|
||||
LoggerDecorator.music(logger, "Lavalink нода переподключена");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Ошибка health-check Lavalink", e);
|
||||
}
|
||||
}
|
||||
|
||||
public LavalinkClient getClient() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue