mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2024-11-29 13:45:16 +01:00
#1147 Drop SingleFilePersistenceHandler in favor of DistributedFilesPersistenceHandler
- Remove SingleFilePersistenceHandler: DistributedFilesPersistenceHandler with segment size 1 can be used instead - Rename SegmentFilesPersistenceHolder to DistributedFilesPersistenceHandler - Rename SeparateFilePersistenceHandler to IndividualFilesPersistenceHandler to match LimboPersistenceType entry - Add link to limbo page on Wiki in the settings
This commit is contained in:
parent
a764598f88
commit
adb007108d
@ -1,5 +1,5 @@
|
||||
<!-- AUTO-GENERATED FILE! Do not edit this directly -->
|
||||
<!-- File auto-generated on Wed Mar 22 23:10:33 CET 2017. See docs/config/config.tpl.md -->
|
||||
<!-- File auto-generated on Tue Mar 28 21:38:52 CEST 2017. See docs/config/config.tpl.md -->
|
||||
|
||||
## AuthMe Configuration
|
||||
The first time you run AuthMe it will create a config.yml file in the plugins/AuthMe folder,
|
||||
@ -163,9 +163,6 @@ settings:
|
||||
teleportUnAuthedToSpawn: false
|
||||
# Can unregistered players walk around?
|
||||
allowMovement: false
|
||||
# Should not authenticated players have speed = 0?
|
||||
# This will reset the fly/walk speed to default value after the login.
|
||||
removeSpeed: true
|
||||
# After how many seconds should players who fail to login or register
|
||||
# be kicked? Set to 0 to disable.
|
||||
timeout: 30
|
||||
@ -451,24 +448,25 @@ Security:
|
||||
# such as OP status, ability to fly, and walk/fly speed.
|
||||
# Once the user is logged in, we add back the properties we previously saved.
|
||||
# In this section, you may define how these properties should be handled.
|
||||
# Read more at https://github.com/AuthMe/AuthMeReloaded/wiki/Limbo-players
|
||||
limbo:
|
||||
persistence:
|
||||
# Besides storing the data in memory, you can define if/how the data should be persisted
|
||||
# on disk. This is useful in case of a server crash, so next time the server starts we can
|
||||
# properly restore things like OP status, ability to fly, and walk/fly speed.
|
||||
# DISABLED: no disk storage, INDIVIDUAL_FILES: each player data in its own file,
|
||||
# SINGLE_FILE: all data in one single file (only if you have a small server!)
|
||||
# SEGMENT_FILES: distributes players into different buckets based on their UUID. See below.
|
||||
# DISABLED: no disk storage,
|
||||
# INDIVIDUAL_FILES: each player data in its own file,
|
||||
# DISTRIBUTED_FILES: distributes players into different files based on their UUID, see below
|
||||
type: 'INDIVIDUAL_FILES'
|
||||
# This setting only affects SEGMENT_FILES persistence. The segment file
|
||||
# This setting only affects DISTRIBUTED_FILES persistence. The segment file
|
||||
# persistence attempts to reduce the number of files by distributing players into various
|
||||
# buckets based on their UUID. This setting defines into how many files the players should
|
||||
# be distributed. Possible values: ONE, FOUR, EIGHT, SIXTEEN, THIRTY_TWO, SIXTY_FOUR,
|
||||
# ONE_TWENTY for 128, TWO_FIFTY for 256.
|
||||
# For example, if you expect 100 non-logged in players, setting to SIXTEEN will average
|
||||
# 6.25 players per file (100 / 16). If you set to ONE, like persistence SINGLE_FILE, only
|
||||
# one file will be used. Contrary to SINGLE_FILE, it won't keep the entries in cache, which
|
||||
# may deliver different results in terms of performance.
|
||||
# 6.25 players per file (100 / 16). If you set to ONE, only one file will be used and the
|
||||
# entries will be kept in memory, reducing the number of times we read from the file.
|
||||
# This may deliver different results in terms of performance.
|
||||
# Note: if you change this setting all data will be migrated. If you have a lot of data,
|
||||
# change this setting only on server restart, not with /authme reload.
|
||||
segmentDistribution: 'SIXTEEN'
|
||||
@ -511,4 +509,4 @@ To change settings on a running server, save your changes to config.yml and use
|
||||
|
||||
---
|
||||
|
||||
This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Wed Mar 22 23:10:33 CET 2017
|
||||
This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Tue Mar 28 21:38:52 CEST 2017
|
||||
|
@ -30,7 +30,7 @@ import java.util.Optional;
|
||||
* Persistence handler for LimboPlayer objects by distributing the objects to store
|
||||
* in various segments (buckets) based on the start of the player's UUID.
|
||||
*/
|
||||
class SegmentFilesPersistenceHolder implements LimboPersistenceHandler {
|
||||
class DistributedFilesPersistenceHandler implements LimboPersistenceHandler {
|
||||
|
||||
private static final Type LIMBO_MAP_TYPE = new TypeToken<Map<String, LimboPlayer>>(){}.getType();
|
||||
|
||||
@ -39,7 +39,7 @@ class SegmentFilesPersistenceHolder implements LimboPersistenceHandler {
|
||||
private final SegmentNameBuilder segmentNameBuilder;
|
||||
|
||||
@Inject
|
||||
SegmentFilesPersistenceHolder(@DataFolder File dataFolder, BukkitService bukkitService, Settings settings) {
|
||||
DistributedFilesPersistenceHandler(@DataFolder File dataFolder, BukkitService bukkitService, Settings settings) {
|
||||
cacheFolder = new File(dataFolder, "playerdata");
|
||||
if (!cacheFolder.exists()) {
|
||||
// TODO ljacqu 20170313: Create FileUtils#mkdirs
|
||||
@ -100,7 +100,7 @@ class SegmentFilesPersistenceHolder implements LimboPersistenceHandler {
|
||||
|
||||
@Override
|
||||
public LimboPersistenceType getType() {
|
||||
return LimboPersistenceType.SEGMENT_FILES;
|
||||
return LimboPersistenceType.DISTRIBUTED_FILES;
|
||||
}
|
||||
|
||||
private void saveEntries(Map<String, LimboPlayer> entries, File file) {
|
||||
@ -126,7 +126,11 @@ class SegmentFilesPersistenceHolder implements LimboPersistenceHandler {
|
||||
|
||||
private File getPlayerSegmentFile(String uuid) {
|
||||
String segment = segmentNameBuilder.createSegmentName(uuid);
|
||||
return new File(cacheFolder, segment + "-limbo.json");
|
||||
return getSegmentFile(segment);
|
||||
}
|
||||
|
||||
private File getSegmentFile(String segmentId) {
|
||||
return new File(cacheFolder, segmentId + "-limbo.json");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -167,7 +171,7 @@ class SegmentFilesPersistenceHolder implements LimboPersistenceHandler {
|
||||
ConsoleLogger.info("Saving " + limbosFromOldSegments.size() + " LimboPlayers from old segments into "
|
||||
+ limboBySegment.size() + " current segments");
|
||||
for (Map.Entry<String, Map<String, LimboPlayer>> entry : limboBySegment.entrySet()) {
|
||||
File file = new File(cacheFolder, entry.getKey() + "-limbo.json");
|
||||
File file = getSegmentFile(entry.getKey());
|
||||
Map<String, LimboPlayer> limbosToSave = Optional.ofNullable(readLimboPlayers(file))
|
||||
.orElseGet(HashMap::new);
|
||||
limbosToSave.putAll(entry.getValue());
|
||||
@ -193,7 +197,7 @@ class SegmentFilesPersistenceHolder implements LimboPersistenceHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes files from the current segmenting scheme that are empty.
|
||||
* Deletes segment files that are empty.
|
||||
*/
|
||||
private void deleteEmptyFiles() {
|
||||
File[] files = listFiles(cacheFolder);
|
@ -19,13 +19,13 @@ import java.nio.charset.StandardCharsets;
|
||||
/**
|
||||
* Saves LimboPlayer objects as JSON into individual files.
|
||||
*/
|
||||
class SeparateFilePersistenceHandler implements LimboPersistenceHandler {
|
||||
class IndividualFilesPersistenceHandler implements LimboPersistenceHandler {
|
||||
|
||||
private final Gson gson;
|
||||
private final File cacheDir;
|
||||
|
||||
@Inject
|
||||
SeparateFilePersistenceHandler(@DataFolder File dataFolder, BukkitService bukkitService) {
|
||||
IndividualFilesPersistenceHandler(@DataFolder File dataFolder, BukkitService bukkitService) {
|
||||
cacheDir = new File(dataFolder, "playerdata");
|
||||
if (!cacheDir.exists() && !cacheDir.isDirectory() && !cacheDir.mkdir()) {
|
||||
ConsoleLogger.warning("Failed to create playerdata directory '" + cacheDir + "'");
|
@ -6,13 +6,10 @@ package fr.xephi.authme.data.limbo.persistence;
|
||||
public enum LimboPersistenceType {
|
||||
|
||||
/** Store each LimboPlayer in a separate file. */
|
||||
INDIVIDUAL_FILES(SeparateFilePersistenceHandler.class),
|
||||
INDIVIDUAL_FILES(IndividualFilesPersistenceHandler.class),
|
||||
|
||||
/** Store all LimboPlayers in the same file. */
|
||||
SINGLE_FILE(SingleFilePersistenceHandler.class),
|
||||
|
||||
/** Distribute LimboPlayers by segments into a set number of files. */
|
||||
SEGMENT_FILES(SegmentFilesPersistenceHolder.class),
|
||||
/** Store LimboPlayers distributed in a configured number of files. */
|
||||
DISTRIBUTED_FILES(DistributedFilesPersistenceHandler.class),
|
||||
|
||||
/** No persistence to disk. */
|
||||
DISABLED(NoOpPersistenceHandler.class);
|
||||
|
@ -3,7 +3,7 @@ package fr.xephi.authme.data.limbo.persistence;
|
||||
/**
|
||||
* Configuration for the total number of segments to use.
|
||||
* <p>
|
||||
* The {@link SegmentFilesPersistenceHolder} reduces the number of files by assigning each UUID
|
||||
* The {@link DistributedFilesPersistenceHandler} reduces the number of files by assigning each UUID
|
||||
* to a segment. This enum allows to define how many segments the UUIDs should be distributed in.
|
||||
* <p>
|
||||
* Segments are defined by a <b>distribution</b> and a <b>length.</b> The distribution defines
|
||||
@ -86,7 +86,7 @@ public enum SegmentConfiguration {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of segments to which this configuration will distribute UUIDs
|
||||
* @return number of segments to which this configuration will distribute all UUIDs
|
||||
*/
|
||||
public int getTotalSegments() {
|
||||
return (int) Math.pow(distribution, length);
|
||||
|
@ -4,7 +4,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Creates segment names for {@link SegmentFilesPersistenceHolder}.
|
||||
* Creates segment names for {@link DistributedFilesPersistenceHandler}.
|
||||
*/
|
||||
class SegmentNameBuilder {
|
||||
|
||||
|
@ -1,94 +0,0 @@
|
||||
package fr.xephi.authme.data.limbo.persistence;
|
||||
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.data.limbo.LimboPlayer;
|
||||
import fr.xephi.authme.initialization.DataFolder;
|
||||
import fr.xephi.authme.service.BukkitService;
|
||||
import fr.xephi.authme.util.FileUtils;
|
||||
import fr.xephi.authme.util.PlayerUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* Saves all LimboPlayers in one JSON file and keeps the entries in memory.
|
||||
*/
|
||||
class SingleFilePersistenceHandler implements LimboPersistenceHandler {
|
||||
|
||||
private final File cacheFile;
|
||||
private final Gson gson;
|
||||
private Map<String, LimboPlayer> entries;
|
||||
|
||||
@Inject
|
||||
SingleFilePersistenceHandler(@DataFolder File dataFolder, BukkitService bukkitService) {
|
||||
cacheFile = new File(dataFolder, "limbo.json");
|
||||
if (!cacheFile.exists()) {
|
||||
FileUtils.create(cacheFile);
|
||||
}
|
||||
|
||||
gson = new GsonBuilder()
|
||||
.registerTypeAdapter(LimboPlayer.class, new LimboPlayerSerializer())
|
||||
.registerTypeAdapter(LimboPlayer.class, new LimboPlayerDeserializer(bukkitService))
|
||||
.setPrettyPrinting()
|
||||
.create();
|
||||
|
||||
Type type = new TypeToken<ConcurrentMap<String, LimboPlayer>>(){}.getType();
|
||||
try (FileReader fr = new FileReader(cacheFile)) {
|
||||
entries = gson.fromJson(fr, type);
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.logException("Failed to read from '" + cacheFile + "':", e);
|
||||
}
|
||||
|
||||
if (entries == null) {
|
||||
entries = new ConcurrentHashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LimboPlayer getLimboPlayer(Player player) {
|
||||
return entries.get(PlayerUtils.getUUIDorName(player));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveLimboPlayer(Player player, LimboPlayer limbo) {
|
||||
entries.put(PlayerUtils.getUUIDorName(player), limbo);
|
||||
saveEntries("adding '" + player.getName() + "'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLimboPlayer(Player player) {
|
||||
LimboPlayer entry = entries.remove(PlayerUtils.getUUIDorName(player));
|
||||
if (entry != null) {
|
||||
saveEntries("removing '" + player.getName() + "'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the entries to the disk.
|
||||
*
|
||||
* @param action the reason for saving (for logging purposes)
|
||||
*/
|
||||
private void saveEntries(String action) {
|
||||
try (FileWriter fw = new FileWriter(cacheFile)) {
|
||||
gson.toJson(entries, fw);
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.logException("Failed saving JSON limbo cache after " + action, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LimboPersistenceType getType() {
|
||||
return LimboPersistenceType.SINGLE_FILE;
|
||||
}
|
||||
}
|
@ -23,28 +23,29 @@ public final class LimboSettings implements SettingsHolder {
|
||||
"Besides storing the data in memory, you can define if/how the data should be persisted",
|
||||
"on disk. This is useful in case of a server crash, so next time the server starts we can",
|
||||
"properly restore things like OP status, ability to fly, and walk/fly speed.",
|
||||
"DISABLED: no disk storage, INDIVIDUAL_FILES: each player data in its own file,",
|
||||
"SINGLE_FILE: all data in one single file (only if you have a small server!)",
|
||||
"SEGMENT_FILES: distributes players into different buckets based on their UUID. See below."
|
||||
"DISABLED: no disk storage,",
|
||||
"INDIVIDUAL_FILES: each player data in its own file,",
|
||||
"DISTRIBUTED_FILES: distributes players into different files based on their UUID, see below"
|
||||
})
|
||||
public static final Property<LimboPersistenceType> LIMBO_PERSISTENCE_TYPE =
|
||||
newProperty(LimboPersistenceType.class, "limbo.persistence.type", LimboPersistenceType.INDIVIDUAL_FILES);
|
||||
|
||||
@Comment({
|
||||
"This setting only affects SEGMENT_FILES persistence. The segment file",
|
||||
"This setting only affects DISTRIBUTED_FILES persistence. The segment file",
|
||||
"persistence attempts to reduce the number of files by distributing players into various",
|
||||
"buckets based on their UUID. This setting defines into how many files the players should",
|
||||
"be distributed. Possible values: ONE, FOUR, EIGHT, SIXTEEN, THIRTY_TWO, SIXTY_FOUR,",
|
||||
"ONE_TWENTY for 128, TWO_FIFTY for 256.",
|
||||
"For example, if you expect 100 non-logged in players, setting to SIXTEEN will average",
|
||||
"6.25 players per file (100 / 16). If you set to ONE, like persistence SINGLE_FILE, only",
|
||||
"one file will be used. Contrary to SINGLE_FILE, it won't keep the entries in cache, which",
|
||||
"may deliver different results in terms of performance.",
|
||||
"6.25 players per file (100 / 16). If you set to ONE, only one file will be used and the",
|
||||
"entries will be kept in memory, reducing the number of times we read from the file.",
|
||||
"This may deliver different results in terms of performance.",
|
||||
"Note: if you change this setting all data will be migrated. If you have a lot of data,",
|
||||
"change this setting only on server restart, not with /authme reload."
|
||||
})
|
||||
public static final Property<SegmentConfiguration> SEGMENT_DISTRIBUTION =
|
||||
newProperty(SegmentConfiguration.class, "limbo.persistence.segmentDistribution", SegmentConfiguration.SIXTEEN);
|
||||
newProperty(SegmentConfiguration.class, "limbo.persistence.segmentDistribution",
|
||||
SegmentConfiguration.SIXTEEN);
|
||||
|
||||
@Comment({
|
||||
"Whether the player is allowed to fly: RESTORE, ENABLE, DISABLE.",
|
||||
@ -79,7 +80,8 @@ public final class LimboSettings implements SettingsHolder {
|
||||
"Before a user logs in, various properties are temporarily removed from the player,",
|
||||
"such as OP status, ability to fly, and walk/fly speed.",
|
||||
"Once the user is logged in, we add back the properties we previously saved.",
|
||||
"In this section, you may define how these properties should be handled."
|
||||
"In this section, you may define how these properties should be handled.",
|
||||
"Read more at https://github.com/AuthMe/AuthMeReloaded/wiki/Limbo-players"
|
||||
};
|
||||
return ImmutableMap.of("limbo", limboExplanation);
|
||||
}
|
||||
|
@ -37,10 +37,10 @@ import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Test for {@link SegmentFilesPersistenceHolder}.
|
||||
* Test for {@link DistributedFilesPersistenceHandler}.
|
||||
*/
|
||||
@RunWith(DelayedInjectionRunner.class)
|
||||
public class SegmentFilesPersistenceHolderTest {
|
||||
public class DistributedFilesPersistenceHandlerTest {
|
||||
|
||||
/** Player is in seg32-10110 and should be migrated into seg16-f. */
|
||||
private static final UUID MIGRATED_UUID = fromString("f6a97c88-7c8f-c12e-4931-6206d4ca067d");
|
||||
@ -70,7 +70,7 @@ public class SegmentFilesPersistenceHolderTest {
|
||||
|
||||
|
||||
@InjectDelayed
|
||||
private SegmentFilesPersistenceHolder persistenceHandler;
|
||||
private DistributedFilesPersistenceHandler persistenceHandler;
|
||||
|
||||
@Mock
|
||||
private Settings settings;
|
@ -30,16 +30,16 @@ import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Test for {@link SeparateFilePersistenceHandler}.
|
||||
* Test for {@link IndividualFilesPersistenceHandler}.
|
||||
*/
|
||||
@RunWith(DelayedInjectionRunner.class)
|
||||
public class SeparateFilePersistenceHandlerTest {
|
||||
public class IndividualFilesPersistenceHandlerTest {
|
||||
|
||||
private static final UUID SAMPLE_UUID = UUID.nameUUIDFromBytes("PersistenceTest".getBytes());
|
||||
private static final String SOURCE_FOLDER = TestHelper.PROJECT_ROOT + "data/backup/";
|
||||
|
||||
@InjectDelayed
|
||||
private SeparateFilePersistenceHandler handler;
|
||||
private IndividualFilesPersistenceHandler handler;
|
||||
|
||||
@Mock
|
||||
private BukkitService bukkitService;
|
Loading…
Reference in New Issue
Block a user