mirror of
https://github.com/WiIIiam278/HuskSync.git
synced 2025-12-23 16:49:19 +00:00
refactor: Reconnect to Redis when connection lost (#230)
* Add redis reconnection * Add separated method to handle thread unlock * Add reconnection time constant
This commit is contained in:
@@ -41,12 +41,16 @@ import java.util.logging.Level;
|
|||||||
public class RedisManager extends JedisPubSub {
|
public class RedisManager extends JedisPubSub {
|
||||||
|
|
||||||
protected static final String KEY_NAMESPACE = "husksync:";
|
protected static final String KEY_NAMESPACE = "husksync:";
|
||||||
|
private static final int RECONNECTION_TIME = 8000;
|
||||||
|
|
||||||
private final HuskSync plugin;
|
private final HuskSync plugin;
|
||||||
private final String clusterId;
|
private final String clusterId;
|
||||||
private Pool<Jedis> jedisPool;
|
private Pool<Jedis> jedisPool;
|
||||||
private final Map<UUID, CompletableFuture<Optional<DataSnapshot.Packed>>> pendingRequests;
|
private final Map<UUID, CompletableFuture<Optional<DataSnapshot.Packed>>> pendingRequests;
|
||||||
|
|
||||||
|
private boolean enabled;
|
||||||
|
private boolean reconnected;
|
||||||
|
|
||||||
public RedisManager(@NotNull HuskSync plugin) {
|
public RedisManager(@NotNull HuskSync plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.clusterId = plugin.getSettings().getClusterId();
|
this.clusterId = plugin.getSettings().getClusterId();
|
||||||
@@ -88,18 +92,53 @@ public class RedisManager extends JedisPubSub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Subscribe using a thread (rather than a task)
|
// Subscribe using a thread (rather than a task)
|
||||||
|
enabled = true;
|
||||||
new Thread(this::subscribe, "husksync:redis_subscriber").start();
|
new Thread(this::subscribe, "husksync:redis_subscriber").start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Blocking
|
@Blocking
|
||||||
private void subscribe() {
|
private void subscribe() {
|
||||||
|
while (enabled && !Thread.interrupted() && jedisPool != null && !jedisPool.isClosed()) {
|
||||||
try (Jedis jedis = jedisPool.getResource()) {
|
try (Jedis jedis = jedisPool.getResource()) {
|
||||||
|
if (reconnected) {
|
||||||
|
plugin.log(Level.INFO, "Redis connection is alive again");
|
||||||
|
}
|
||||||
|
// Subscribe channels and lock the thread
|
||||||
jedis.subscribe(
|
jedis.subscribe(
|
||||||
this,
|
this,
|
||||||
Arrays.stream(RedisMessage.Type.values())
|
Arrays.stream(RedisMessage.Type.values())
|
||||||
.map(type -> type.getMessageChannel(clusterId))
|
.map(type -> type.getMessageChannel(clusterId))
|
||||||
.toArray(String[]::new)
|
.toArray(String[]::new)
|
||||||
);
|
);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
// Thread was unlocked due error
|
||||||
|
onThreadUnlock(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onThreadUnlock(Throwable t) {
|
||||||
|
if (enabled) {
|
||||||
|
if (reconnected) {
|
||||||
|
plugin.log(Level.WARNING,
|
||||||
|
"Connection to the Redis server was lost. Attempting reconnection in 8 seconds...", t);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.unsubscribe();
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
// empty catch
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make an instant subscribe if occurs any error on initialization
|
||||||
|
if (!reconnected) {
|
||||||
|
reconnected = true;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
Thread.sleep(RECONNECTION_TIME);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,6 +175,16 @@ public class RedisManager extends JedisPubSub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSubscribe(String channel, int subscribedChannels) {
|
||||||
|
plugin.log(Level.INFO, "Redis subscribed to channel '" + channel + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUnsubscribe(String channel, int subscribedChannels) {
|
||||||
|
plugin.log(Level.INFO, "Redis unsubscribed from channel '" + channel + "'");
|
||||||
|
}
|
||||||
|
|
||||||
@Blocking
|
@Blocking
|
||||||
protected void sendMessage(@NotNull String channel, @NotNull String message) {
|
protected void sendMessage(@NotNull String channel, @NotNull String message) {
|
||||||
try (Jedis jedis = jedisPool.getResource()) {
|
try (Jedis jedis = jedisPool.getResource()) {
|
||||||
@@ -329,6 +378,7 @@ public class RedisManager extends JedisPubSub {
|
|||||||
|
|
||||||
@Blocking
|
@Blocking
|
||||||
public void terminate() {
|
public void terminate() {
|
||||||
|
enabled = false;
|
||||||
if (jedisPool != null) {
|
if (jedisPool != null) {
|
||||||
if (!jedisPool.isClosed()) {
|
if (!jedisPool.isClosed()) {
|
||||||
jedisPool.close();
|
jedisPool.close();
|
||||||
|
|||||||
Reference in New Issue
Block a user