Refactored PingTable#insertPing to a transaction

This commit is contained in:
Rsl1122 2019-02-01 18:44:42 +02:00
parent b23235b50b
commit 5b3d687a60
12 changed files with 132 additions and 126 deletions

View File

@ -24,8 +24,9 @@
package com.djrapitops.plan.system.tasks.bukkit;
import com.djrapitops.plan.data.store.objects.DateObj;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.Processors;
import com.djrapitops.plan.db.access.transactions.events.PingStoreTransaction;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.TimeSettings;
import com.djrapitops.plan.utilities.java.Reflection;
@ -107,20 +108,20 @@ public class PingCountTimerBukkit extends AbsRunnable implements Listener {
private final Map<UUID, List<DateObj<Integer>>> playerHistory;
private final PlanConfig config;
private final Processors processors;
private final Processing processing;
private final DBSystem dbSystem;
private final ServerInfo serverInfo;
private final RunnableFactory runnableFactory;
@Inject
public PingCountTimerBukkit(
PlanConfig config,
Processors processors,
Processing processing,
DBSystem dbSystem,
ServerInfo serverInfo,
RunnableFactory runnableFactory
) {
this.config = config;
this.processors = processors;
this.processing = processing;
this.dbSystem = dbSystem;
this.serverInfo = serverInfo;
this.runnableFactory = runnableFactory;
playerHistory = new HashMap<>();
}
@ -153,7 +154,9 @@ public class PingCountTimerBukkit extends AbsRunnable implements Listener {
}
history.add(new DateObj<>(time, ping));
if (history.size() >= 30) {
processing.submit(processors.player().pingInsertProcessor(uuid, new ArrayList<>(history)));
dbSystem.getDatabase().executeTransaction(
new PingStoreTransaction(uuid, serverInfo.getServerUUID(), new ArrayList<>(history))
);
history.clear();
}
} else {

View File

@ -24,8 +24,9 @@
package com.djrapitops.plan.system.tasks.bungee;
import com.djrapitops.plan.data.store.objects.DateObj;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.Processors;
import com.djrapitops.plan.db.access.transactions.events.PingStoreTransaction;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.TimeSettings;
import com.djrapitops.plugin.api.TimeAmount;
@ -58,20 +59,20 @@ public class PingCountTimerBungee extends AbsRunnable implements Listener {
private final Map<UUID, List<DateObj<Integer>>> playerHistory;
private final PlanConfig config;
private final Processors processors;
private final Processing processing;
private final DBSystem dbSystem;
private final ServerInfo serverInfo;
private final RunnableFactory runnableFactory;
@Inject
public PingCountTimerBungee(
PlanConfig config,
Processors processors,
Processing processing,
DBSystem dbSystem,
ServerInfo serverInfo,
RunnableFactory runnableFactory
) {
this.config = config;
this.processors = processors;
this.processing = processing;
this.dbSystem = dbSystem;
this.serverInfo = serverInfo;
this.runnableFactory = runnableFactory;
playerHistory = new HashMap<>();
}
@ -94,7 +95,9 @@ public class PingCountTimerBungee extends AbsRunnable implements Listener {
}
history.add(new DateObj<>(time, ping));
if (history.size() >= 30) {
processing.submit(processors.player().pingInsertProcessor(uuid, new ArrayList<>(history)));
dbSystem.getDatabase().executeTransaction(
new PingStoreTransaction(uuid, serverInfo.getServerUUID(), new ArrayList<>(history))
);
history.clear();
}
} else {

View File

@ -17,6 +17,7 @@
package com.djrapitops.plan.db.access.queries;
import com.djrapitops.plan.data.container.GeoInfo;
import com.djrapitops.plan.data.container.Ping;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.data.store.keys.SessionKeys;
import com.djrapitops.plan.data.time.GMTimes;
@ -239,4 +240,26 @@ public class DataStoreQueries {
}
};
}
/**
* Store Ping data of a player on a server.
*
* @param playerUUID UUID of the player.
* @param serverUUID UUID of the Plan server.
* @param ping Ping data entry
* @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction}
*/
public static Executable storePing(UUID playerUUID, UUID serverUUID, Ping ping) {
return new ExecStatement(PingTable.INSERT_STATEMENT) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, playerUUID.toString());
statement.setString(2, serverUUID.toString());
statement.setLong(3, ping.getDate());
statement.setInt(4, ping.getMin());
statement.setInt(5, ping.getMax());
statement.setDouble(6, ping.getAverage());
}
};
}
}

View File

@ -14,13 +14,14 @@
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.system.processing.processors.player;
package com.djrapitops.plan.db.access.transactions.events;
import com.djrapitops.plan.data.container.Ping;
import com.djrapitops.plan.data.store.objects.DateObj;
import com.djrapitops.plan.db.Database;
import com.djrapitops.plan.system.processing.CriticalRunnable;
import com.djrapitops.plan.db.access.queries.DataStoreQueries;
import com.djrapitops.plan.db.access.transactions.Transaction;
import com.djrapitops.plan.utilities.analysis.Median;
import com.google.common.annotations.VisibleForTesting;
import java.util.List;
import java.util.OptionalInt;
@ -28,62 +29,62 @@ import java.util.UUID;
import java.util.stream.Collectors;
/**
* Processes 60s values of a Ping list.
* <p>
* Ping list contains 30 values as ping is updated every 2 seconds.
* Transaction to store player's Ping value on a server.
*
* @author Rsl1122
*/
public class PingInsertProcessor implements CriticalRunnable {
public class PingStoreTransaction extends Transaction {
private final UUID uuid;
private final UUID playerUUID;
private final UUID serverUUID;
private final List<DateObj<Integer>> pingList;
private final Database database;
private OptionalInt max;
PingInsertProcessor(
UUID uuid, UUID serverUUID, List<DateObj<Integer>> pingList,
Database database
) {
this.uuid = uuid;
public PingStoreTransaction(UUID playerUUID, UUID serverUUID, List<DateObj<Integer>> pingList) {
this.playerUUID = playerUUID;
this.serverUUID = serverUUID;
this.pingList = pingList;
this.database = database;
}
@Override
public void run() {
List<DateObj<Integer>> history = pingList;
long lastDate = history.get(history.size() - 1).getDate();
OptionalInt max = history.stream()
.mapToInt(DateObj::getValue)
.filter(i -> i > 0 && i < 4000)
.max();
if (!max.isPresent()) {
return;
}
int minValue = getMinValue(history);
int meanValue = getMeanValue(history);
int maxValue = max.getAsInt();
Ping ping = new Ping(lastDate, serverUUID, minValue, maxValue, meanValue);
database.save().ping(uuid, ping);
protected boolean shouldBeExecuted() {
max = getMax();
return max.isPresent();
}
int getMinValue(List<DateObj<Integer>> history) {
return history.stream()
@Override
protected void performOperations() {
Ping ping = calculateAggregatePing();
execute(DataStoreQueries.storePing(playerUUID, serverUUID, ping));
}
private Ping calculateAggregatePing() {
long lastDate = pingList.get(pingList.size() - 1).getDate();
int minValue = getMinValue();
int meanValue = getMeanValue();
int maxValue = max.getAsInt();
return new Ping(lastDate, serverUUID, minValue, maxValue, meanValue);
}
private int getMinValue() {
return pingList.stream()
.mapToInt(DateObj::getValue)
.filter(i -> i > 0 && i < 4000)
.min().orElse(-1);
}
int getMeanValue(List<DateObj<Integer>> history) {
return (int) Median.forList(history.stream().map(DateObj::getValue).collect(Collectors.toList())).calculate();
private OptionalInt getMax() {
return pingList.stream()
.mapToInt(DateObj::getValue)
.filter(i -> i > 0 && i < 4000)
.max();
}
}
@VisibleForTesting
int getMeanValue() {
return (int) Median.forList(pingList.stream().map(DateObj::getValue).collect(Collectors.toList())).calculate();
}
}

View File

@ -16,18 +16,12 @@
*/
package com.djrapitops.plan.db.sql.tables;
import com.djrapitops.plan.data.container.Ping;
import com.djrapitops.plan.db.DBType;
import com.djrapitops.plan.db.SQLDB;
import com.djrapitops.plan.db.access.ExecStatement;
import com.djrapitops.plan.db.patches.PingOptimizationPatch;
import com.djrapitops.plan.db.sql.parsing.CreateTableParser;
import com.djrapitops.plan.db.sql.parsing.Sql;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.UUID;
/**
* Table that represents plan_ping in the database.
* <p>
@ -72,18 +66,4 @@ public class PingTable extends Table {
.column(AVG_PING, Sql.DOUBLE).notNull()
.toString();
}
public void insertPing(UUID uuid, Ping ping) {
execute(new ExecStatement(INSERT_STATEMENT) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, uuid.toString());
statement.setString(2, getServerUUID().toString());
statement.setLong(3, ping.getDate());
statement.setInt(4, ping.getMin());
statement.setInt(5, ping.getMax());
statement.setDouble(6, ping.getAverage());
}
});
}
}

View File

@ -17,7 +17,10 @@
package com.djrapitops.plan.system.database.databases.operation;
import com.djrapitops.plan.data.WebUser;
import com.djrapitops.plan.data.container.*;
import com.djrapitops.plan.data.container.GeoInfo;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.data.container.TPS;
import com.djrapitops.plan.data.container.UserInfo;
import com.djrapitops.plan.data.store.objects.Nickname;
import com.djrapitops.plan.system.info.server.Server;
import com.djrapitops.plan.system.settings.config.Config;
@ -88,9 +91,6 @@ public interface SaveOperations {
@Deprecated
void webUser(WebUser webUser);
@Deprecated
void ping(UUID uuid, Ping ping);
@Deprecated
void setAsUninstalled(UUID serverUUID);

View File

@ -172,11 +172,6 @@ public class SQLSaveOps extends SQLOps implements SaveOperations {
securityTable.addNewUser(webUser);
}
@Override
public void ping(UUID uuid, Ping ping) {
pingTable.insertPing(uuid, ping);
}
@Override
public void setAsUninstalled(UUID serverUUID) {
serverTable.setAsUninstalled(serverUUID);

View File

@ -16,7 +16,6 @@
*/
package com.djrapitops.plan.system.processing.processors.player;
import com.djrapitops.plan.data.store.objects.DateObj;
import com.djrapitops.plan.data.store.objects.Nickname;
import com.djrapitops.plan.system.cache.DataCache;
import com.djrapitops.plan.system.cache.GeolocationCache;
@ -27,7 +26,6 @@ import dagger.Lazy;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.List;
import java.util.UUID;
import java.util.function.BooleanSupplier;
@ -76,9 +74,4 @@ public class PlayerProcessors {
Nickname nickname = new Nickname(displayName, System.currentTimeMillis(), serverInfo.get().getServerUUID());
return new NameProcessor(uuid, nickname, dbSystem.get().getDatabase(), dataCache.get());
}
public PingInsertProcessor pingInsertProcessor(UUID uuid, List<DateObj<Integer>> pingList) {
return new PingInsertProcessor(uuid, serverInfo.get().getServerUUID(), pingList, dbSystem.get().getDatabase());
}
}

View File

@ -25,6 +25,7 @@ import com.djrapitops.plan.data.store.containers.NetworkContainer;
import com.djrapitops.plan.data.store.containers.PlayerContainer;
import com.djrapitops.plan.data.store.containers.ServerContainer;
import com.djrapitops.plan.data.store.keys.*;
import com.djrapitops.plan.data.store.objects.DateObj;
import com.djrapitops.plan.data.store.objects.Nickname;
import com.djrapitops.plan.data.time.GMTimes;
import com.djrapitops.plan.data.time.WorldTimes;
@ -562,10 +563,10 @@ public abstract class CommonDBTest {
tpsTable.insertTPS(tps);
}
pingTable.insertPing(playerUUID, new Ping(
System.currentTimeMillis(), serverUUID,
r.nextInt(), r.nextInt(), r.nextDouble()
));
db.executeTransaction(new PingStoreTransaction(
playerUUID, serverUUID,
Collections.singletonList(new DateObj<>(System.currentTimeMillis(), r.nextInt())))
);
securityTable.addNewUser(new WebUser(TestConstants.PLAYER_ONE_NAME, "RandomGarbageBlah", 0));
}

View File

@ -14,7 +14,7 @@
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.system.processing.processors.player;
package com.djrapitops.plan.db.access.transactions.events;
import com.djrapitops.plan.data.store.objects.DateObj;
import com.djrapitops.plan.utilities.analysis.Median;
@ -32,11 +32,11 @@ import java.util.stream.Collectors;
import static org.junit.Assert.assertEquals;
/**
* Test for {@link PingInsertProcessor}.
* Test for {@link PingStoreTransaction#getMeanValue()}.
*
* @author Rsl1122
*/
public class PingInsertProcessorTest {
public class PingMedianTest {
private List<DateObj<Integer>> testPing;
@ -54,8 +54,8 @@ public class PingInsertProcessorTest {
List<Integer> collect = testPing.stream().map(DateObj::getValue).sorted().collect(Collectors.toList());
int expected = (int) Median.forList(collect).calculate();
int result = new PingInsertProcessor(TestConstants.PLAYER_ONE_UUID, TestConstants.SERVER_UUID, new ArrayList<>(), null)
.getMeanValue(testPing);
int result = new PingStoreTransaction(TestConstants.PLAYER_ONE_UUID, TestConstants.SERVER_UUID, new ArrayList<>())
.getMeanValue();
assertEquals(expected, result);
}
@ -63,8 +63,9 @@ public class PingInsertProcessorTest {
@Test
public void medianCalculationForSingleEntry() {
int expected = 50;
int result = new PingInsertProcessor(TestConstants.PLAYER_ONE_UUID, TestConstants.SERVER_UUID, new ArrayList<>(), null)
.getMeanValue(Collections.singletonList(new DateObj<>(0, expected)));
int result = new PingStoreTransaction(TestConstants.PLAYER_ONE_UUID, TestConstants.SERVER_UUID,
Collections.singletonList(new DateObj<>(0, expected)))
.getMeanValue();
assertEquals(expected, result);
}
@ -72,8 +73,8 @@ public class PingInsertProcessorTest {
@Test
public void medianCalculationForNoEntries() {
int expected = -1;
int result = new PingInsertProcessor(TestConstants.PLAYER_ONE_UUID, TestConstants.SERVER_UUID, new ArrayList<>(), null)
.getMeanValue(Collections.emptyList());
int result = new PingStoreTransaction(TestConstants.PLAYER_ONE_UUID, TestConstants.SERVER_UUID, new ArrayList<>())
.getMeanValue();
assertEquals(expected, result);
}

View File

@ -24,8 +24,9 @@
package com.djrapitops.plan.system.tasks.sponge;
import com.djrapitops.plan.data.store.objects.DateObj;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.Processors;
import com.djrapitops.plan.db.access.transactions.events.PingStoreTransaction;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.TimeSettings;
import com.djrapitops.plugin.api.TimeAmount;
@ -54,20 +55,20 @@ public class PingCountTimerSponge extends AbsRunnable {
private final Map<UUID, List<DateObj<Integer>>> playerHistory;
private final PlanConfig config;
private final Processors processors;
private final Processing processing;
private final DBSystem dbSystem;
private final ServerInfo serverInfo;
private final RunnableFactory runnableFactory;
@Inject
public PingCountTimerSponge(
PlanConfig config,
Processors processors,
Processing processing,
DBSystem dbSystem,
ServerInfo serverInfo,
RunnableFactory runnableFactory
) {
this.config = config;
this.processors = processors;
this.processing = processing;
this.dbSystem = dbSystem;
this.serverInfo = serverInfo;
this.runnableFactory = runnableFactory;
playerHistory = new HashMap<>();
}
@ -90,7 +91,9 @@ public class PingCountTimerSponge extends AbsRunnable {
}
history.add(new DateObj<>(time, ping));
if (history.size() >= 30) {
processing.submit(processors.player().pingInsertProcessor(uuid, new ArrayList<>(history)));
dbSystem.getDatabase().executeTransaction(
new PingStoreTransaction(uuid, serverInfo.getServerUUID(), new ArrayList<>(history))
);
history.clear();
}
} else {

View File

@ -25,8 +25,9 @@ package com.djrapitops.plan.system.tasks.velocity;
import com.djrapitops.plan.PlanVelocity;
import com.djrapitops.plan.data.store.objects.DateObj;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.Processors;
import com.djrapitops.plan.db.access.transactions.events.PingStoreTransaction;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.TimeSettings;
import com.djrapitops.plugin.api.TimeAmount;
@ -60,22 +61,22 @@ public class PingCountTimerVelocity extends AbsRunnable {
private final PlanVelocity plugin;
private final PlanConfig config;
private final Processors processors;
private final Processing processing;
private final DBSystem dbSystem;
private final ServerInfo serverInfo;
private final RunnableFactory runnableFactory;
@Inject
public PingCountTimerVelocity(
PlanVelocity plugin,
PlanConfig config,
Processors processors,
Processing processing,
DBSystem dbSystem,
ServerInfo serverInfo,
RunnableFactory runnableFactory
) {
this.plugin = plugin;
this.config = config;
this.processors = processors;
this.processing = processing;
this.dbSystem = dbSystem;
this.serverInfo = serverInfo;
this.runnableFactory = runnableFactory;
playerHistory = new HashMap<>();
}
@ -98,7 +99,9 @@ public class PingCountTimerVelocity extends AbsRunnable {
}
history.add(new DateObj<>(time, ping));
if (history.size() >= 30) {
processing.submit(processors.player().pingInsertProcessor(uuid, new ArrayList<>(history)));
dbSystem.getDatabase().executeTransaction(
new PingStoreTransaction(uuid, serverInfo.getServerUUID(), new ArrayList<>(history))
);
history.clear();
}
} else {