Add heartbeat timeout

This commit is contained in:
Colin McDonald 2016-06-25 18:55:48 -04:00
parent fde7d50edc
commit 8d1fb524ec
2 changed files with 43 additions and 1 deletions

View File

@ -12,6 +12,7 @@ import fr.javatic.mongo.jacksonCodec.objectId.Id;
import lombok.Getter;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.serialization.gson.ExcludeFromReplies;
import net.frozenorb.apiv3.util.TimeUtils;
import org.bson.Document;
import java.time.Instant;
@ -46,6 +47,7 @@ public final class Server {
static {
updateCache();
APIv3.getVertxInstance().setPeriodic(TimeUnit.MINUTES.toMillis(1), (id) -> updateCache());
APIv3.getVertxInstance().setPeriodic(TimeUnit.MINUTES.toMillis(1), (id) -> updateTimedOutServers());
}
private static void updateCache() {
@ -66,6 +68,42 @@ public final class Server {
});
}
// TODO: This code isn't multi-instance safe AND will send more
// db requests than needed.
private static void updateTimedOutServers() {
for (Server server : serverCache) {
int lastUpdatedAgo = TimeUtils.getSecondsBetween(server.getLastUpdatedAt(), Instant.now());
if (lastUpdatedAgo < TimeUnit.SECONDS.toSeconds(30)) {
return;
}
for (UUID online : server.getPlayers()) {
User.findById(online, (user, error) -> {
if (error != null) {
error.printStackTrace();
return;
}
if (user.leftServer(server)) {
user.save((ignored, error2) -> {
if (error2 != null) {
error2.printStackTrace();
}
});
}
});
}
server.players = new HashSet<>();
server.save((ignored, error) -> {
if (error != null) {
error.printStackTrace();
}
});
}
}
private Server() {} // For Jackson
public Server(String id, String displayName, String apiKey, ServerGroup serverGroup, String serverIp) {

View File

@ -349,12 +349,16 @@ public final class User {
return true;
}
public void leftServer(Server server) {
// Returns if any change was actually made.
public boolean leftServer(Server server) {
// We have this check to prevent issues where one server's
// leave is processed after another server's login.
if (server.getId().equals(lastSeenOn)) {
this.lastSeenAt = Instant.now();
this.online = false;
return true;
} else {
return false;
}
}