Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/more caching #272

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 36 additions & 17 deletions src/main/java/com/jagrosh/giveawaybot/commands/ListCmd.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@
import com.jagrosh.giveawaybot.entities.LocalizedMessage;
import com.jagrosh.giveawaybot.util.FormatUtil;
import com.jagrosh.interactions.command.ApplicationCommand;
import com.jagrosh.interactions.entities.AllowedMentions;
import com.jagrosh.interactions.entities.Permission;
import com.jagrosh.interactions.entities.SentMessage;
import com.jagrosh.interactions.entities.*;
import com.jagrosh.interactions.receive.Interaction;
import com.jagrosh.interactions.responses.InteractionResponse;
import com.jagrosh.interactions.responses.MessageCallback;
Expand All @@ -37,6 +35,8 @@
*/
public class ListCmd extends GBCommand
{
private final static int MAX_LENGTH = 6000;

public ListCmd(GiveawayBot bot)
{
super(bot);
Expand All @@ -52,26 +52,45 @@ public ListCmd(GiveawayBot bot)
@Override
protected InteractionResponse gbExecute(Interaction interaction) throws GiveawayException
{
//bot.getGiveawayManager().checkPermission(interaction.getMember(), interaction.getGuildId());

List<Giveaway> list = bot.getDatabase().getGiveawaysByGuild(interaction.getGuildId());
if(list.isEmpty())
return respondError(LocalizedMessage.WARNING_NO_GIVEAWAYS.getLocalizedMessage(interaction.getEffectiveLocale()));
//Color c = bot.getDatabase().getSettings(interaction.getGuildId()).getColor();
StringBuilder sb = new StringBuilder("**Active Giveaways**\n");
list.forEach(giv ->

WebLocale loc = interaction.getEffectiveLocale();
String title = LocalizedMessage.GIVEAWAY_LIST.getLocalizedMessage(interaction.getEffectiveLocale());
int total = title.length();

Embed.Builder eb = new Embed.Builder();
eb.setColor(bot.getDatabase().getSettings(interaction.getGuildId()).getColor());
eb.setTitle(title, null);

for(Giveaway giv: list)
{
sb.append("\n[`").append(giv.getMessageId()).append("`](").append(giv.getJumpLink()).append(") | <#").append(giv.getChannelId()).append("> | **").append(giv.getWinners())
.append("** ").append(FormatUtil.pluralise(giv.getWinners(), "winner", "winners")).append(" | ")
.append(giv.getPrize() == null || giv.getPrize().isEmpty() ? "No prize specified" : "Prize: **" + giv.getPrize() + "**").append(" | ")
.append("Host: <@").append(giv.getUserId()).append("> | ")
.append("Ends in ").append(FormatUtil.secondsToTime(Instant.now().until(giv.getEndInstant(), ChronoUnit.SECONDS)));

});
String key = giv.getPrize().isEmpty() ? "Giveaway" : giv.getPrize();
String val = renderGiveawayString(giv, loc);
if(total + key.length() + val.length() >= MAX_LENGTH - 4)
{
eb.setFooter("...", null);
break;
}
eb.addField(key, val, true);
total += key.length() + val.length();
}
return new MessageCallback(new SentMessage.Builder()
.setContent(sb.toString())
//.setContent(sb.toString())
.setAllowedMentions(new AllowedMentions(true))
//.addEmbed(new Embed.Builder().setTitle("Active Giveaways", null).setColor(c).setDescription(sb.toString()).build())
.addEmbed(eb.build())
.build());
}

private String renderGiveawayString(Giveaway giv, WebLocale loc)
{
return new StringBuilder()
.append("[`").append(giv.getMessageId()).append("`](").append(giv.getJumpLink()).append(") | <#").append(giv.getChannelId()).append("> | ")
//.append(giv.getPrize().isEmpty() ? "" : "**" + giv.getPrize() + "** | ")
.append(LocalizedMessage.GIVEAWAY_WINNERS.getLocalizedMessage(loc)).append(": **").append(giv.getWinners()).append("** | ")
.append(LocalizedMessage.GIVEAWAY_HOSTED.getLocalizedMessage(loc)).append(": <@").append(giv.getUserId()).append("> | ")
.append(LocalizedMessage.GIVEAWAY_ENDS.getLocalizedMessage(loc)).append(": ").append(FormatUtil.secondsToTime(Instant.now().until(giv.getEndInstant(), ChronoUnit.SECONDS)))
.toString();
}
}
54 changes: 32 additions & 22 deletions src/main/java/com/jagrosh/giveawaybot/data/Database.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public class Database
private final EntityManagerFactory emf;
private final EntityManager em;
private final Map<Long, GiveawayEntries> cachedEntries = new HashMap<>();
private final Map<Long, CachedUser> cachedUsers = new HashMap<>();
private final Map<Long, Giveaway> cachedGiveawaysReadonly = new HashMap<>();
private final ScheduledExecutorService cacheCombiner = Executors.newSingleThreadScheduledExecutor();

Expand All @@ -54,13 +55,13 @@ public Database(String host, String user, String pass)
em.getMetamodel().managedType(Giveaway.class);
em.getMetamodel().managedType(GiveawayEntries.class);
em.getMetamodel().managedType(GuildSettings.class);
cacheCombiner.scheduleWithFixedDelay(() -> syncEntries(), 60, 60, TimeUnit.SECONDS);
cacheCombiner.scheduleWithFixedDelay(() -> syncCaches(), 60, 60, TimeUnit.SECONDS);
}

public void shutdown()
{
cacheCombiner.shutdown();
syncEntries();
syncCaches();
em.close();
emf.close();
}
Expand Down Expand Up @@ -204,32 +205,19 @@ public synchronized void removeGiveaway(long id)
// entries
public synchronized void updateUser(User user)
{
// update cached user
CachedUser u = em.find(CachedUser.class, user.getIdLong());

// short circuit if data is up to date
if(u != null
&& OtherUtil.strEquals(user.getUsername(), u.getUsername())
&& OtherUtil.strEquals(user.getDiscriminator(), u.getDiscriminator())
&& OtherUtil.strEquals(user.getAvatar(), u.getAvatar()))
return;

em.getTransaction().begin();
if(u == null)
{
u = new CachedUser();
u.setId(user.getIdLong());
em.persist(u);
}
// construct a cached user object and cache immediately
// this will reach the database when we sync
CachedUser u = new CachedUser();
u.setId(user.getIdLong());
u.setUsername(user.getUsername());
u.setDiscriminator(user.getDiscriminator());
u.setAvatar(user.getAvatar());
em.getTransaction().commit();
cachedUsers.put(user.getIdLong(), u);
}

public CachedUser getUser(long userId)
{
return em.find(CachedUser.class, userId);
return cachedUsers.containsKey(userId) ? cachedUsers.get(userId) : em.find(CachedUser.class, userId);
}

public synchronized int addEntry(long giveawayId, User user)
Expand Down Expand Up @@ -276,12 +264,34 @@ public synchronized boolean removeEntry(long giveawayId, User user)
return true;
}

public synchronized void syncEntries()
public synchronized void syncCaches()
{
// open transaction
em.getTransaction().begin();

// update entries
cachedEntries.values().forEach(e -> em.merge(e));

// update users
cachedUsers.values().forEach(user ->
{
CachedUser u = em.find(CachedUser.class, user.getId());
if(u == null)
{
em.persist(user);
}
else
{
u.setUsername(user.getUsername());
u.setDiscriminator(user.getDiscriminator());
u.setAvatar(user.getAvatar());
}
});

// commit the transaction
em.getTransaction().commit();
cachedEntries.clear();
cachedUsers.clear();
}

public List<CachedUser> getEntriesList(long giveawayId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ public enum LocalizedMessage
GIVEAWAY_HOSTED("giveaway.hosted"),
GIVEAWAY_ENTRIES("giveaway.entries"),
GIVEAWAY_WINNERS("giveaway.winners"),
GIVEAWAY_SUMMARY("giveaway.summary");
GIVEAWAY_SUMMARY("giveaway.summary"),
GIVEAWAY_LIST("giveaway.list");

private final static String FILENAME = "localization/messages";
private final String key;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void shutdown()
private void check()
{
double req = bot.getInteractionsClient().getMetrics().getOrDefault("TotalTime", 0L) / bot.getInteractionsClient().getMetrics().getOrDefault("TotalRequests", 1L) * 1e-9;
if(req > 1)
if(req > .5)
bot.shutdown("AUTOMATIC: avg req = " + req);
}
}
1 change: 1 addition & 0 deletions src/main/resources/localization/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,5 @@ giveaway.hosted = Hosted by
giveaway.entries = Entries
giveaway.winners = Winners
giveaway.summary = Giveaway Summary
giveaway.list = Active Giveaways