Use redis pub/sub to send booster updates

This commit is contained in:
Shaun Bennett 2016-06-10 12:44:27 -05:00
parent 08e47b4b1b
commit 0a204a3b90
6 changed files with 197 additions and 35 deletions

View File

@ -10,7 +10,7 @@ import java.util.UUID;
*/
public class Booster
{
private int _boosterId;
private int _id;
private String _playerName;
private UUID _uuid;
private int _accountId;
@ -24,9 +24,9 @@ public class Booster
{
}
public int getBoosterId()
public int getId()
{
return _boosterId;
return _id;
}
public String getPlayerName()
@ -66,7 +66,7 @@ public class Booster
public boolean isActive()
{
return getEndTime().before(new Date());
return getEndTime().after(new Date());
}
public long getTimeRemaining()
@ -92,14 +92,14 @@ public class Booster
Booster booster = (Booster) o;
if (_boosterId != booster._boosterId) return false;
if (_id != booster._id) return false;
return _accountId == booster._accountId;
}
@Override
public int hashCode()
{
int result = _boosterId;
int result = _id;
result = 31 * result + _accountId;
return result;
}
@ -108,7 +108,7 @@ public class Booster
public String toString()
{
return "Booster{" +
"_boosterId=" + _boosterId +
"_id=" + _id +
", _playerName='" + _playerName + '\'' +
", _uuid=" + _uuid +
", _accountId=" + _accountId +

View File

@ -5,13 +5,16 @@ import mineplex.core.account.CoreClientManager;
import mineplex.core.boosters.command.BoosterCommand;
import mineplex.core.boosters.event.BoosterActivateEvent;
import mineplex.core.boosters.event.BoosterDeactivateEvent;
import mineplex.core.boosters.event.BoosterUpdateEvent;
import mineplex.core.boosters.gui.BoosterShop;
import mineplex.core.boosters.redis.BoosterUpdateRepository;
import mineplex.core.boosters.tips.BoosterTipManager;
import mineplex.core.common.util.Callback;
import mineplex.core.donation.DonationManager;
import mineplex.core.inventory.InventoryManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
@ -58,6 +61,8 @@ public class BoosterManager extends MiniPlugin
System.out.println("Failed to load boosters on server start.");
e.printStackTrace();
}
new BoosterUpdateRepository(plugin);
}
@Override
@ -76,28 +81,7 @@ public class BoosterManager extends MiniPlugin
long timeTaken = System.currentTimeMillis() - time;
runSync(() -> {
_boosterCache.entrySet().stream()
.filter(entry -> entry.getValue().size() > 0)
.filter(entry -> boosters.get(entry.getKey()) == null)
.forEach(entry -> callNextTick(new BoosterDeactivateEvent(entry.getValue().get(0))));
for (Map.Entry<String, List<Booster>> entry : boosters.entrySet())
{
List<Booster> current = _boosterCache.get(entry.getKey());
if (current == null || current.get(0) == null)
{
callNextTick(new BoosterActivateEvent(entry.getValue().get(0)));
}
else if (!current.get(0).equals(entry.getValue().get(0)))
{
callNextTick(new BoosterDeactivateEvent(current.get(0)));
callNextTick(new BoosterActivateEvent(entry.getValue().get(0)));
}
}
_cacheLastUpdated = System.currentTimeMillis();
_boosterCache = boosters;
handleBoosterUpdate(boosters);
if (callback != null) callback.run(boosters);
});
}
@ -109,6 +93,65 @@ public class BoosterManager extends MiniPlugin
});
}
private void handleBoosterUpdate(Map<String, List<Booster>> boosterMap)
{
_boosterCache.entrySet().stream()
.filter(entry -> entry.getValue().size() > 0)
.filter(entry -> boosterMap.get(entry.getKey()) == null)
.forEach(entry -> callNextTick(new BoosterDeactivateEvent(entry.getValue().get(0))));
for (Map.Entry<String, List<Booster>> entry : boosterMap.entrySet())
{
List<Booster> current = _boosterCache.get(entry.getKey());
if (current == null || current.get(0) == null)
{
callNextTick(new BoosterActivateEvent(entry.getValue().get(0)));
}
else if (!current.get(0).equals(entry.getValue().get(0)))
{
callNextTick(new BoosterDeactivateEvent(current.get(0)));
callNextTick(new BoosterActivateEvent(entry.getValue().get(0)));
}
}
_cacheLastUpdated = System.currentTimeMillis();
_boosterCache = boosterMap;
}
private void tickBoosterCache()
{
for (List<Booster> boosters : _boosterCache.values())
{
Iterator<Booster> iterator = boosters.iterator();
boolean removedOne = false;
while (iterator.hasNext())
{
Booster booster = iterator.next();
if (!booster.isActive())
{
iterator.remove();
removedOne = true;
System.out.println("booster removed from tick");
Bukkit.getPluginManager().callEvent(new BoosterDeactivateEvent(booster));
}
else
{
if (removedOne) Bukkit.getPluginManager().callEvent(new BoosterActivateEvent(booster));
break;
}
}
}
}
@EventHandler
public void tickBoosters(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
return;
tickBoosterCache();
}
public Booster getActiveBoosterFromCache(String serverGroup)
{
List<Booster> boosters = _boosterCache.get(serverGroup);
@ -158,12 +201,9 @@ public class BoosterManager extends MiniPlugin
}
@EventHandler
public void updateCache(UpdateEvent event)
public void onBoosterUpdate(BoosterUpdateEvent event)
{
if (event.getType() == UpdateType.SEC_30)
{
getBoostersAsync(null);
}
handleBoosterUpdate(event.getBoosterMap());
}
public BoosterTipManager getTipManager()

View File

@ -0,0 +1,39 @@
package mineplex.core.boosters.event;
import mineplex.core.boosters.Booster;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import java.util.List;
import java.util.Map;
/**
* @author Shaun Bennett
*/
public class BoosterUpdateEvent extends Event
{
private Map<String, List<Booster>> _boosterMap;
public BoosterUpdateEvent(Map<String, List<Booster>> boosterMap)
{
_boosterMap = boosterMap;
}
public Map<String, List<Booster>> getBoosterMap()
{
return _boosterMap;
}
private static final HandlerList _handlers = new HandlerList();
private static HandlerList getHandlerList()
{
return _handlers;
}
@Override
public HandlerList getHandlers()
{
return getHandlerList();
}
}

View File

@ -0,0 +1,44 @@
package mineplex.core.boosters.redis;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import mineplex.core.boosters.Booster;
import mineplex.core.boosters.event.BoosterUpdateEvent;
import mineplex.core.common.api.ApiFieldNamingStrategy;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import redis.clients.jedis.JedisPubSub;
import java.util.List;
import java.util.Map;
/**
* @author Shaun Bennett
*/
public class BoosterUpdateListener extends JedisPubSub
{
private Gson _gson = new GsonBuilder().setFieldNamingStrategy(new ApiFieldNamingStrategy())
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX").create();
private JavaPlugin _plugin;
public BoosterUpdateListener(JavaPlugin plugin)
{
_plugin = plugin;
}
@Override
public void onMessage(String channel, String message)
{
try
{
Map<String, List<Booster>> boosterMap = _gson.fromJson(message, new TypeToken<Map<String, List<Booster>>>() {}.getType());
_plugin.getServer().getScheduler().runTask(_plugin, () -> Bukkit.getPluginManager().callEvent(new BoosterUpdateEvent(boosterMap)));
}
catch (Exception e)
{
System.out.println("Failed to load booster update");
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,39 @@
package mineplex.core.boosters.redis;
import mineplex.serverdata.Region;
import mineplex.serverdata.redis.RedisRepository;
import org.bukkit.plugin.java.JavaPlugin;
import redis.clients.jedis.Jedis;
/**
* @author Shaun Bennett
*/
public class BoosterUpdateRepository extends RedisRepository
{
private JavaPlugin _plugin;
public BoosterUpdateRepository(JavaPlugin plugin)
{
super(Region.ALL);
_plugin = plugin;
init();
}
private void init()
{
Thread thread = new Thread("Booster Subscriber")
{
@Override
public void run()
{
try (Jedis jedis = new Jedis())
{
jedis.subscribe(new BoosterUpdateListener(_plugin), "minecraft.boosters");
}
}
};
thread.start();
}
}

View File

@ -57,7 +57,7 @@ public class BoosterTipManager extends MiniDbClientPlugin<PlayerTipData>
runAsync(() -> {
TipAddResult result;
if (_repository.addTip(accountId, booster.getAccountId(), booster.getBoosterId(), TIP_FOR_SPONSOR))
if (_repository.addTip(accountId, booster.getAccountId(), booster.getId(), TIP_FOR_SPONSOR))
{
_donationManager.rewardCoinsUntilSuccess(null, "Tips", player.getName(), accountId, TIP_FOR_TIPPER);
result = TipAddResult.SUCCESS;