From b80a41ebe7a24201db1fd102cbfc13676b3dcdd0 Mon Sep 17 00:00:00 2001 From: cnr Date: Fri, 17 Feb 2017 20:29:09 -0600 Subject: [PATCH] Reduce refresh rate of communities Communities will only be refreshed if: - We know (via redis message) that the community has been changed (e.g., if a member joins/leaves, if an invite is sent, ...). - Five minutes have passed since a full refresh --- .../core/communities/CommunityManager.java | 37 +++++++++++++++++-- .../storage/CommunityRepository.java | 5 +-- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/communities/CommunityManager.java b/Plugins/Mineplex.Core/src/mineplex/core/communities/CommunityManager.java index 509c65f57..19a6a5609 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/communities/CommunityManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/communities/CommunityManager.java @@ -8,6 +8,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Pattern; @@ -70,6 +71,8 @@ import mineplex.serverdata.servers.ServerRepository; public class CommunityManager extends MiniDbClientPlugin { + private final int UPDATE_CYCLE_SECONDS = 10; // The number of seconds between dirty communities refreshes + private final int CACHE_INVALIDATION_SECONDS = 300; // The number of seconds between full communities refreshes public final Pattern ALPHA_NUMERIC_PATTERN = Pattern.compile("[^A-Za-z0-9]"); public final String[] BLOCKED_NAMES = new String[] {"help", "chat", "create", "description", "disband", "invite", "join", "mcs", "rename", "uninvite", "trainee", "mod", "moderator", "srmod", "seniormod", "seniormoderator", "builder", "maplead", "twitch", "youtube", "support", "admin", "administrator", "leader", "dev", "developer", "owner", "party", "mineplex", "mineplexOfficial", "staff", "mineplexstaff", "qualityassurance", "traineemanagement", "modcoordination", "forumninja", "communitymanagement", "event", "socialmedia"}; private final CommunityRepository _repo; @@ -82,7 +85,9 @@ public class CommunityManager extends MiniDbClientPlugin private ServerRepository _serverRepo; private boolean _us; - + + private final Set dirty = Collections.newSetFromMap(new ConcurrentHashMap<>()); // Communities with redis updates + private int _updateCycleCount; // The number of update cycles since we've updated all communities private volatile boolean _cycling = false; @SuppressWarnings("deprecation") @@ -132,15 +137,30 @@ public class CommunityManager extends MiniDbClientPlugin Bukkit.getScheduler().scheduleAsyncRepeatingTask(plugin, () -> { + _updateCycleCount++; + if (_cycling) { return; } - + LinkedList communities = new LinkedList<>(); - _loadedCommunities.values().forEach(community -> communities.add(community)); + if (UPDATE_CYCLE_SECONDS * _updateCycleCount > CACHE_INVALIDATION_SECONDS) + { + // It's been five minutes since a full update; update all communities + _updateCycleCount = 0; + dirty.clear(); + + _loadedCommunities.values().forEach(communities::add); + } + else + { + dirty.forEach(communities::add); + dirty.clear(); + } + _repo.updateMembersAndJoinRequests(communities); - }, 0L, 20 * 10); + }, 0L, 20 * UPDATE_CYCLE_SECONDS); Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, () -> { @@ -221,6 +241,7 @@ public class CommunityManager extends MiniDbClientPlugin { return; } + dirty.add(community); setting.parseValueInto(newValue, community); //community.message(F.main(getName(), F.name(sender) + " has changed settings in " + F.name(community.getName()) + "!")); runSync(() -> UtilServer.CallEvent(new CommunitySettingUpdateEvent(community))); @@ -233,6 +254,7 @@ public class CommunityManager extends MiniDbClientPlugin { return; } + dirty.add(community); String oldName = community.getName(); community.setName(name); community.message(F.main(getName(), F.name(sender) + " has changed the name of " + F.name(oldName) + " to " + F.name(community.getName()) + "!")); @@ -246,6 +268,7 @@ public class CommunityManager extends MiniDbClientPlugin { return; } + dirty.add(community); CommunityMemberInfo member = community.getMembers().get(uuid); member.updateRole(role); if (Bukkit.getPlayer(uuid) != null) @@ -268,6 +291,7 @@ public class CommunityManager extends MiniDbClientPlugin { return; } + dirty.add(community); if (kick) { @@ -316,6 +340,7 @@ public class CommunityManager extends MiniDbClientPlugin { return; } + dirty.add(community); runSync(() -> { if (Bukkit.getPlayer(targetUUID) != null) @@ -342,6 +367,7 @@ public class CommunityManager extends MiniDbClientPlugin { return; } + dirty.add(community); runSync(() -> { if (Bukkit.getPlayer(targetUUID) != null) @@ -367,6 +393,7 @@ public class CommunityManager extends MiniDbClientPlugin { return; } + dirty.add(community); if (Bukkit.getPlayer(playerUUID) != null) { UtilPlayer.message(Bukkit.getPlayer(playerUUID), F.main(getName(), "You have requested to join " + F.elem(community.getName()) + "!")); @@ -384,6 +411,7 @@ public class CommunityManager extends MiniDbClientPlugin { return; } + dirty.add(community); community.getJoinRequests().remove(playerUUID); if (announce) { @@ -406,6 +434,7 @@ public class CommunityManager extends MiniDbClientPlugin runSync(() -> { Community community = _loadedCommunities.get(id); + dirty.add(community); if (Bukkit.getPlayer(leaderUUID) != null) { Player leader = Bukkit.getPlayer(leaderUUID); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/communities/storage/CommunityRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/communities/storage/CommunityRepository.java index abba4f955..4d9d45992 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/communities/storage/CommunityRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/communities/storage/CommunityRepository.java @@ -19,7 +19,6 @@ import mineplex.core.communities.CommunityJoinRequestInfo; import mineplex.core.communities.CommunityMemberInfo; import mineplex.core.communities.CommunityRole; import mineplex.core.communities.CommunitySetting; -import mineplex.core.database.MinecraftRepository; import mineplex.serverdata.data.DataRepository; import mineplex.serverdata.data.PlayerStatus; import mineplex.serverdata.database.DBPool; @@ -152,7 +151,7 @@ public class CommunityRepository extends RepositoryBase return; } - TimingManager.start("members + join requests"); + TimingManager.start("members + join requests for " + communities.size() + " communities"); Map statuses = _repo.getElementsMap( Stream.concat( communities.stream().flatMap(community -> community.getMembers().keySet().stream()), @@ -208,7 +207,7 @@ public class CommunityRepository extends RepositoryBase } } } - TimingManager.stop("members + join requests"); + TimingManager.stop("members + join requests for " + communities.size() + " communities"); } public void updateJoinRequests(LinkedList communities)