Resolve more synchronization issues.

Notably, getLastOnline() is more in sync, putting a probable end to #23!
This commit is contained in:
Tux 2015-10-03 23:36:37 -04:00
parent e285b3f2aa
commit 4e09efe801
3 changed files with 21 additions and 8 deletions

View File

@ -317,34 +317,37 @@ public final class RedisBungee extends Plugin {
public void run() { public void run() {
try (Jedis tmpRsc = pool.getResource()) { try (Jedis tmpRsc = pool.getResource()) {
Set<String> players = getLocalPlayersAsUuidStrings(); Set<String> players = getLocalPlayersAsUuidStrings();
Set<String> redisCollection = tmpRsc.smembers("proxy:" + configuration.getServerId() + ":usersOnline"); Set<String> playersInRedis = tmpRsc.smembers("proxy:" + configuration.getServerId() + ":usersOnline");
for (String member : redisCollection) { for (Iterator<String> it = playersInRedis.iterator(); it.hasNext(); ) {
String member = it.next();
if (!players.contains(member)) { if (!players.contains(member)) {
// Are they simply on a different proxy? // Are they simply on a different proxy?
boolean found = false; String found = null;
for (String proxyId : getServerIds()) { for (String proxyId : getServerIds()) {
if (proxyId.equals(configuration.getServerId())) continue; if (proxyId.equals(configuration.getServerId())) continue;
if (tmpRsc.sismember("proxy:" + proxyId + ":usersOnline", member)) { if (tmpRsc.sismember("proxy:" + proxyId + ":usersOnline", member)) {
// Just clean up the set. // Just clean up the set.
found = true; found = proxyId;
break; break;
} }
} }
if (!found) { if (found == null) {
RedisUtil.cleanUpPlayer(member, tmpRsc); RedisUtil.cleanUpPlayer(member, tmpRsc);
getLogger().warning("Player found in set that was not found locally and globally: " + member); getLogger().warning("Player found in set that was not found locally and globally: " + member);
} else { } else {
tmpRsc.srem("proxy:" + configuration.getServerId() + ":usersOnline", member); tmpRsc.srem("proxy:" + configuration.getServerId() + ":usersOnline", member);
getLogger().warning("Player found in set that was not found locally, but is on another proxy: " + member); getLogger().warning("Player found in set that was not found locally, but is on another proxy: " + member);
} }
it.remove();
} }
} }
Pipeline pipeline = tmpRsc.pipelined(); Pipeline pipeline = tmpRsc.pipelined();
for (String player : players) { for (String player : players) {
if (redisCollection.contains(player)) if (playersInRedis.contains(player))
continue; continue;
// Player not online according to Redis but not BungeeCord. // Player not online according to Redis but not BungeeCord.
@ -354,7 +357,7 @@ public final class RedisBungee extends Plugin {
if (proxiedPlayer == null) if (proxiedPlayer == null)
continue; // We'll deal with it later. continue; // We'll deal with it later.
RedisUtil.createPlayer(proxiedPlayer.getPendingConnection(), pipeline); RedisUtil.createPlayer(proxiedPlayer, pipeline);
} }
pipeline.sync(); pipeline.sync();

View File

@ -140,7 +140,6 @@ public class RedisBungeeListener implements Listener {
protected Void call(Jedis jedis) { protected Void call(Jedis jedis) {
Pipeline pipeline = jedis.pipelined(); Pipeline pipeline = jedis.pipelined();
long timestamp = System.currentTimeMillis(); long timestamp = System.currentTimeMillis();
pipeline.hset("player:" + event.getPlayer().getUniqueId().toString(), "online", String.valueOf(timestamp));
RedisUtil.cleanUpPlayer(event.getPlayer().getUniqueId().toString(), pipeline); RedisUtil.cleanUpPlayer(event.getPlayer().getUniqueId().toString(), pipeline);
pipeline.publish("redisbungee-data", RedisBungee.getGson().toJson(new DataManager.DataManagerMessage<>( pipeline.publish("redisbungee-data", RedisBungee.getGson().toJson(new DataManager.DataManagerMessage<>(
event.getPlayer().getUniqueId(), DataManager.DataManagerMessage.Action.LEAVE, event.getPlayer().getUniqueId(), DataManager.DataManagerMessage.Action.LEAVE,

View File

@ -30,6 +30,7 @@ import com.google.common.annotations.VisibleForTesting;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import net.md_5.bungee.api.connection.PendingConnection; import net.md_5.bungee.api.connection.PendingConnection;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline; import redis.clients.jedis.Pipeline;
@ -39,6 +40,12 @@ import java.util.Map;
@VisibleForTesting @VisibleForTesting
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PRIVATE)
public class RedisUtil { public class RedisUtil {
protected static void createPlayer(ProxiedPlayer player, Pipeline pipeline) {
createPlayer(player.getPendingConnection(), pipeline);
if (player.getServer() != null)
pipeline.hset("player:" + player.getUniqueId().toString(), "server", player.getServer().getInfo().getName());
}
protected static void createPlayer(PendingConnection connection, Pipeline pipeline) { protected static void createPlayer(PendingConnection connection, Pipeline pipeline) {
Map<String, String> playerData = new HashMap<>(4); Map<String, String> playerData = new HashMap<>(4);
playerData.put("online", "0"); playerData.put("online", "0");
@ -55,6 +62,8 @@ public class RedisUtil {
rsc.hdel("player:" + player, "server"); rsc.hdel("player:" + player, "server");
rsc.hdel("player:" + player, "ip"); rsc.hdel("player:" + player, "ip");
rsc.hdel("player:" + player, "proxy"); rsc.hdel("player:" + player, "proxy");
long timestamp = System.currentTimeMillis();
rsc.hset("player:" + player, "online", String.valueOf(timestamp));
} }
public static void cleanUpPlayer(String player, Pipeline rsc) { public static void cleanUpPlayer(String player, Pipeline rsc) {
@ -62,6 +71,8 @@ public class RedisUtil {
rsc.hdel("player:" + player, "server"); rsc.hdel("player:" + player, "server");
rsc.hdel("player:" + player, "ip"); rsc.hdel("player:" + player, "ip");
rsc.hdel("player:" + player, "proxy"); rsc.hdel("player:" + player, "proxy");
long timestamp = System.currentTimeMillis();
rsc.hset("player:" + player, "online", String.valueOf(timestamp));
} }
public static boolean canUseLua(String redisVersion) { public static boolean canUseLua(String redisVersion) {