Mineplex2018-withcommit/Plugins/Mineplex.ReportServer/src/mineplex/reportserver/RedisConnectionHandler.java

107 lines
2.6 KiB
Java

package mineplex.reportserver;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.time.DurationFormatUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
/**
* Establishes and maintains a connection to Redis.
*/
public class RedisConnectionHandler implements Runnable
{
private final String _name;
private final JedisPool _jedisPool;
private final RedisCommandHandler _handler;
private final String[] _channels;
private final Logger _logger;
private long _lastConnectionMillis = -1;
private Throwable _lastThrowable = null;
public RedisConnectionHandler(String name, JedisPool jedisPool, RedisCommandHandler handler, String[] channels, Logger logger)
{
_name = name;
_jedisPool = jedisPool;
_handler = handler;
_channels = channels;
_logger = logger;
Validate.isTrue(channels.length > 0, "Must provide at least one channel.");
}
@Override
public void run()
{
while (!Thread.interrupted())
{
try
{
registerChannelHandlers();
}
catch (Throwable e)
{
// Only log new errors (prevents same error being spammed)
if (_lastThrowable == null || !e.getClass().equals(_lastThrowable.getClass()))
{
if (_lastThrowable == null) // connection just failed
{
_lastConnectionMillis = System.currentTimeMillis();
}
_logger.log(Level.SEVERE, prefixMessage(
"Exception in Redis connection"
+ (_lastConnectionMillis != -1 ? " (no connection for " + getLastConnectionDuration() + ")" : "")
+ ", attempting to regain connection."
), e);
_lastThrowable = e;
}
try
{
Thread.sleep(1000 * 5);
}
catch (InterruptedException ignored) {}
}
}
_jedisPool.destroy();
_logger.warning("Thread interrupted, end of connection.");
}
private void registerChannelHandlers()
{
try (Jedis jedis = _jedisPool.getResource())
{
connectionEstablished();
jedis.subscribe(_handler, _channels);
}
}
private void connectionEstablished()
{
// subscribe blocks so we need to do all this before
_logger.info(
_lastThrowable == null
? prefixMessage("Connected.")
: prefixMessage(String.format("Connected after %s.", getLastConnectionDuration()))
);
_lastThrowable = null;
}
private String prefixMessage(String message)
{
return String.format("[%s] %s", _name, message);
}
private String getLastConnectionDuration()
{
return DurationFormatUtils.formatDurationWords(System.currentTimeMillis() - _lastConnectionMillis, true, true);
}
}