1
0
mirror of https://github.com/essentials/Essentials.git synced 2025-08-11 17:15:07 +02:00

Queued writing of the files to reduce disk io

This commit is contained in:
snowleo
2012-10-07 22:18:30 +02:00
parent 7a36150f3c
commit 524531a090
22 changed files with 247 additions and 284 deletions

View File

@@ -24,6 +24,7 @@ import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import static net.ess3.I18n._; import static net.ess3.I18n._;
import net.ess3.api.*; import net.ess3.api.*;
import net.ess3.backup.Backup; import net.ess3.backup.Backup;
@@ -36,6 +37,7 @@ import net.ess3.metrics.Metrics;
import net.ess3.ranks.RanksStorage; import net.ess3.ranks.RanksStorage;
import net.ess3.settings.SettingsHolder; import net.ess3.settings.SettingsHolder;
import net.ess3.settings.SpawnsHolder; import net.ess3.settings.SpawnsHolder;
import net.ess3.storage.StorageQueue;
import net.ess3.user.UserMap; import net.ess3.user.UserMap;
import net.ess3.utils.ExecuteTimer; import net.ess3.utils.ExecuteTimer;
import org.bukkit.Server; import org.bukkit.Server;
@@ -46,22 +48,34 @@ import org.bukkit.plugin.InvalidDescriptionException;
public class Essentials implements IEssentials public class Essentials implements IEssentials
{ {
@Getter
private transient ISettings settings; private transient ISettings settings;
@Getter
private transient IJails jails; private transient IJails jails;
@Getter
private transient IKits kits; private transient IKits kits;
@Getter
private transient IWarps warps; private transient IWarps warps;
@Getter
private transient IWorth worth; private transient IWorth worth;
private transient List<IReload> reloadList; @Getter
private transient IBackup backup; private transient IBackup backup;
@Getter
private transient IItemDb itemDb; private transient IItemDb itemDb;
private transient IRanks groups; @Getter
@Setter
private transient IRanks ranks;
@Getter
private transient SpawnsHolder spawns; private transient SpawnsHolder spawns;
@Getter
private transient final Methods paymentMethod = new Methods(); private transient final Methods paymentMethod = new Methods();
@Getter
private transient IUserMap userMap; private transient IUserMap userMap;
private transient ExecuteTimer execTimer;
@Getter @Getter
private final I18n i18n; private final I18n i18n;
@Getter
private transient ICommandHandler commandHandler; private transient ICommandHandler commandHandler;
@Getter
private transient Economy economy; private transient Economy economy;
@Getter @Getter
private final Server server; private final Server server;
@@ -69,28 +83,29 @@ public class Essentials implements IEssentials
private final Logger logger; private final Logger logger;
@Getter @Getter
private final IPlugin plugin; private final IPlugin plugin;
public static boolean testing; @Getter
@Setter
private transient Metrics metrics; private transient Metrics metrics;
@Getter @Getter
private transient EssentialsTimer timer; private transient EssentialsTimer timer;
@Getter @Getter
private transient List<String> vanishedPlayers = new ArrayList<String>(); private transient List<String> vanishedPlayers = new ArrayList<String>();
@Getter
private final transient StorageQueue storageQueue;
private transient ExecuteTimer execTimer;
public static boolean testing;
private transient List<IReload> reloadList;
public Essentials(final Server server, final Logger logger, final IPlugin plugin) public Essentials(final Server server, final Logger logger, final IPlugin plugin)
{ {
this.server = server; this.server = server;
this.logger = logger; this.logger = logger;
this.plugin = plugin; this.plugin = plugin;
this.storageQueue = new StorageQueue(plugin);
this.i18n = new I18n(this); this.i18n = new I18n(this);
i18n.onEnable(); i18n.onEnable();
} }
@Override
public ISettings getSettings()
{
return settings;
}
public void setupForTesting(final Server server) throws IOException, InvalidDescriptionException public void setupForTesting(final Server server) throws IOException, InvalidDescriptionException
{ {
testing = true; testing = true;
@@ -106,6 +121,7 @@ public class Essentials implements IEssentials
logger.log(Level.INFO, I18n._("usingTempFolderForTesting")); logger.log(Level.INFO, I18n._("usingTempFolderForTesting"));
logger.log(Level.INFO, dataFolder.toString()); logger.log(Level.INFO, dataFolder.toString());
storageQueue.setEnabled(true);
settings = new SettingsHolder(this); settings = new SettingsHolder(this);
i18n.updateLocale("en"); i18n.updateLocale("en");
userMap = new UserMap(this); userMap = new UserMap(this);
@@ -115,6 +131,7 @@ public class Essentials implements IEssentials
@Override @Override
public void onEnable() public void onEnable()
{ {
storageQueue.setEnabled(true);
execTimer = new ExecuteTimer(); execTimer = new ExecuteTimer();
execTimer.start(); execTimer.start();
@@ -130,8 +147,8 @@ public class Essentials implements IEssentials
userMap = new UserMap(this); userMap = new UserMap(this);
reloadList.add(userMap); reloadList.add(userMap);
execTimer.mark("Init(Usermap)"); execTimer.mark("Init(Usermap)");
groups = new RanksStorage(this); ranks = new RanksStorage(this);
reloadList.add((RanksStorage)groups); reloadList.add((RanksStorage)ranks);
warps = new Warps(this); warps = new Warps(this);
reloadList.add(warps); reloadList.add(warps);
execTimer.mark("Init(Spawn/Warp)"); execTimer.mark("Init(Spawn/Warp)");
@@ -181,6 +198,7 @@ public class Essentials implements IEssentials
} }
i18n.onDisable(); i18n.onDisable();
Trade.closeLog(); Trade.closeLog();
storageQueue.setEnabled(false);
} }
@Override @Override
@@ -197,48 +215,6 @@ public class Essentials implements IEssentials
i18n.updateLocale(settings.getLocale()); i18n.updateLocale(settings.getLocale());
} }
@Override
public IJails getJails()
{
return jails;
}
@Override
public IKits getKits()
{
return kits;
}
@Override
public IWarps getWarps()
{
return warps;
}
@Override
public IWorth getWorth()
{
return worth;
}
@Override
public IBackup getBackup()
{
return backup;
}
@Override
public Metrics getMetrics()
{
return metrics;
}
@Override
public void setMetrics(Metrics metrics)
{
this.metrics = metrics;
}
@Override @Override
public World getWorld(final String name) public World getWorld(final String name)
{ {
@@ -259,12 +235,6 @@ public class Essentials implements IEssentials
reloadList.add(listener); reloadList.add(listener);
} }
@Override
public Methods getPaymentMethod()
{
return paymentMethod;
}
@Override @Override
public int broadcastMessage(final IUser sender, final String message) public int broadcastMessage(final IUser sender, final String message)
{ {
@@ -288,57 +258,9 @@ public class Essentials implements IEssentials
return getServer().getOnlinePlayers().length; return getServer().getOnlinePlayers().length;
} }
@Override
public IItemDb getItemDb()
{
return itemDb;
}
@Override
public IUserMap getUserMap()
{
return userMap;
}
@Override
public IRanks getRanks()
{
return groups;
}
@Override
public ICommandHandler getCommandHandler()
{
return commandHandler;
}
@Override
public void setRanks(final IRanks groups)
{
this.groups = groups;
}
@Override @Override
public void removeReloadListener(IReload groups) public void removeReloadListener(IReload groups)
{ {
this.reloadList.remove(groups); this.reloadList.remove(groups);
} }
@Override
public IEconomy getEconomy()
{
return economy;
}
@Override
public SpawnsHolder getSpawns()
{
return spawns;
}
@Override
public void reload()
{
//do something
}
} }

View File

@@ -31,7 +31,7 @@ public class Jails extends AsyncStorageObjectHolder<net.ess3.settings.Jails> imp
public Jails(final IEssentials ess) public Jails(final IEssentials ess)
{ {
super(ess, net.ess3.settings.Jails.class); super(ess, net.ess3.settings.Jails.class, new File(ess.getPlugin().getDataFolder(), "jail.yml"));
onReload(); onReload();
registerListeners(); registerListeners();
} }
@@ -45,12 +45,6 @@ public class Jails extends AsyncStorageObjectHolder<net.ess3.settings.Jails> imp
pluginManager.registerEvents(playerListener, ess.getPlugin()); pluginManager.registerEvents(playerListener, ess.getPlugin());
} }
@Override
public File getStorageFile()
{
return new File(ess.getPlugin().getDataFolder(), "jail.yml");
}
@Override @Override
public Location getJail(final String jailName) throws Exception public Location getJail(final String jailName) throws Exception
{ {

View File

@@ -19,16 +19,10 @@ public class Kits extends AsyncStorageObjectHolder<net.ess3.settings.Kits> imple
{ {
public Kits(final IEssentials ess) public Kits(final IEssentials ess)
{ {
super(ess, net.ess3.settings.Kits.class); super(ess, net.ess3.settings.Kits.class, new File(ess.getPlugin().getDataFolder(), "kits.yml"));
onReload(); onReload();
} }
@Override
public File getStorageFile() throws IOException
{
return new File(ess.getPlugin().getDataFolder(), "kits.yml");
}
@Override @Override
public Kit getKit(String kitName) throws Exception public Kit getKit(String kitName) throws Exception
{ {

View File

@@ -6,6 +6,7 @@ import net.ess3.EssentialsTimer;
import net.ess3.economy.register.Methods; import net.ess3.economy.register.Methods;
import net.ess3.metrics.Metrics; import net.ess3.metrics.Metrics;
import net.ess3.settings.SpawnsHolder; import net.ess3.settings.SpawnsHolder;
import net.ess3.storage.StorageQueue;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.World; import org.bukkit.World;
@@ -42,8 +43,6 @@ public interface IEssentials extends IComponent
Methods getPaymentMethod(); Methods getPaymentMethod();
void reload();
void setRanks(IRanks groups); void setRanks(IRanks groups);
void removeReloadListener(IReload groups); void removeReloadListener(IReload groups);
@@ -65,4 +64,6 @@ public interface IEssentials extends IComponent
void setMetrics(Metrics metrics); void setMetrics(Metrics metrics);
SpawnsHolder getSpawns(); SpawnsHolder getSpawns();
StorageQueue getStorageQueue();
} }

View File

@@ -51,7 +51,7 @@ public class Commandessentials extends EssentialsCommand
private void run_reload(final CommandSender sender, final String[] args) throws Exception private void run_reload(final CommandSender sender, final String[] args) throws Exception
{ {
ess.reload(); ess.onReload();
sender.sendMessage(_("essentialsReload", ess.getPlugin().getVersion())); sender.sendMessage(_("essentialsReload", ess.getPlugin().getVersion()));
} }
} }

View File

@@ -1,7 +1,6 @@
package net.ess3.economy; package net.ess3.economy;
import java.io.File; import java.io.File;
import java.io.IOException;
import net.ess3.api.IEssentials; import net.ess3.api.IEssentials;
import net.ess3.storage.AsyncStorageObjectHolder; import net.ess3.storage.AsyncStorageObjectHolder;
@@ -24,13 +23,7 @@ public class MoneyHolder extends AsyncStorageObjectHolder<Money>
public MoneyHolder(IEssentials ess) public MoneyHolder(IEssentials ess)
{ {
super(ess, Money.class); super(ess, Money.class, new File(ess.getPlugin().getDataFolder(), "economy_npcs.yml"));
onReload(); onReload();
} }
@Override
public File getStorageFile() throws IOException
{
return new File(ess.getPlugin().getDataFolder(), "economy_npcs.yml");
}
} }

View File

@@ -26,7 +26,7 @@ public class WorthHolder extends AsyncStorageObjectHolder<net.ess3.economy.Worth
public WorthHolder(final IEssentials ess) public WorthHolder(final IEssentials ess)
{ {
super(ess, net.ess3.economy.Worth.class); super(ess, net.ess3.economy.Worth.class, new File(ess.getPlugin().getDataFolder(), "worth.yml"));
onReload(false); onReload(false);
} }
@@ -72,10 +72,4 @@ public class WorthHolder extends AsyncStorageObjectHolder<net.ess3.economy.Worth
getData().setSellPrice(itemStack.getData(), price); getData().setSellPrice(itemStack.getData(), price);
queueSave(); queueSave();
} }
@Override
public File getStorageFile() throws IOException
{
return new File(ess.getPlugin().getDataFolder(), "worth.yml");
}
} }

View File

@@ -30,16 +30,10 @@ public class RanksStorage extends AsyncStorageObjectHolder<Ranks> implements IRa
public RanksStorage(final IEssentials ess) public RanksStorage(final IEssentials ess)
{ {
super(ess, Ranks.class); super(ess, Ranks.class, new File(ess.getPlugin().getDataFolder(), "ranks.yml"));
onReload(); onReload();
} }
@Override
public File getStorageFile()
{
return new File(ess.getPlugin().getDataFolder(), "ranks.yml");
}
public Collection<Entry<String, RankOptions>> getGroups(final IUser player) public Collection<Entry<String, RankOptions>> getGroups(final IUser player)
{ {
final Map<String, RankOptions> groups = getData().getRanks(); final Map<String, RankOptions> groups = getData().getRanks();

View File

@@ -21,7 +21,7 @@ public class SettingsHolder extends AsyncStorageObjectHolder<Settings> implement
public SettingsHolder(final IEssentials ess) public SettingsHolder(final IEssentials ess)
{ {
super(ess, Settings.class); super(ess, Settings.class, new File(ess.getPlugin().getDataFolder(), "settings.yml"));
onReload(); onReload();
} }
@@ -33,12 +33,6 @@ public class SettingsHolder extends AsyncStorageObjectHolder<Settings> implement
debug = getData().getGeneral().isDebug(); debug = getData().getGeneral().isDebug();
} }
@Override
public File getStorageFile()
{
return new File(ess.getPlugin().getDataFolder(), "settings.yml");
}
@Override @Override
public String getLocale() public String getLocale()
{ {

View File

@@ -40,17 +40,11 @@ public class SpawnsHolder extends AsyncStorageObjectHolder<Spawns> implements IE
public SpawnsHolder(final IEssentials ess) public SpawnsHolder(final IEssentials ess)
{ {
super(ess, Spawns.class); super(ess, Spawns.class, new File(ess.getPlugin().getDataFolder(), "spawn.yml"));
onReload(); onReload();
registerListeners(); registerListeners();
} }
@Override
public File getStorageFile()
{
return new File(ess.getPlugin().getDataFolder(), "spawn.yml");
}
public void setSpawn(final Location loc, final String group) public void setSpawn(final Location loc, final String group)
{ {
getData().addSpawn(group, loc); getData().addSpawn(group, loc);

View File

@@ -1,7 +1,5 @@
package net.ess3.settings; package net.ess3.settings;
import java.io.File;
import java.io.IOException;
import net.ess3.api.IEssentials; import net.ess3.api.IEssentials;
import net.ess3.api.IWarp; import net.ess3.api.IWarp;
import net.ess3.api.InvalidNameException; import net.ess3.api.InvalidNameException;
@@ -10,39 +8,21 @@ import net.ess3.storage.AsyncStorageObjectHolder;
public class WarpHolder extends AsyncStorageObjectHolder<Warp> implements IWarp public class WarpHolder extends AsyncStorageObjectHolder<Warp> implements IWarp
{ {
@Override @Override
public void finishRead() public void finishRead()
{ {
} }
@Override @Override
public void finishWrite() public void finishWrite()
{ {
} }
private final String name; private final String name;
public WarpHolder(String name, IEssentials ess) public WarpHolder(String name, IEssentials ess) throws InvalidNameException
{ {
super(ess, Warp.class); super(ess, Warp.class, ess.getWarps().getWarpFile(name));
this.name = name; this.name = name;
onReload(); onReload();
} }
@Override
public File getStorageFile() throws IOException
{
try
{
return ess.getWarps().getWarpFile(name);
}
catch (InvalidNameException ex)
{
throw new IOException(ex.getMessage(), ex);
}
}
} }

View File

@@ -4,7 +4,6 @@ import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level; import java.util.logging.Level;
import net.ess3.api.IEssentials; import net.ess3.api.IEssentials;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@@ -12,10 +11,8 @@ import org.bukkit.Bukkit;
public abstract class AbstractDelayedYamlFileReader<T extends StorageObject> implements Runnable public abstract class AbstractDelayedYamlFileReader<T extends StorageObject> implements Runnable
{ {
private final transient Class<T> clazz; private final transient Class<T> clazz;
private final transient IEssentials ess; private final transient IEssentials ess;
private final transient ReentrantLock lock = new ReentrantLock();
public AbstractDelayedYamlFileReader(final IEssentials ess, final Class<T> clazz) public AbstractDelayedYamlFileReader(final IEssentials ess, final Class<T> clazz)
{ {
@@ -35,16 +32,14 @@ public abstract class AbstractDelayedYamlFileReader<T extends StorageObject> imp
} }
} }
public abstract File onStart() throws IOException; public abstract File onStart();
@Override @Override
public void run() public void run()
{ {
File file = null; final File file = onStart();
lock.lock(); synchronized (file)
try
{ {
file = onStart();
try try
{ {
final FileReader reader = new FileReader(file); final FileReader reader = new FileReader(file);
@@ -69,7 +64,7 @@ public abstract class AbstractDelayedYamlFileReader<T extends StorageObject> imp
catch (FileNotFoundException ex) catch (FileNotFoundException ex)
{ {
onException(ex); onException(ex);
Bukkit.getLogger().log(Level.INFO, "File not found: {0}", file.toString()); Bukkit.getLogger().log(Level.INFO, "File not found: " + file.toString());
} }
catch (ObjectLoadException ex) catch (ObjectLoadException ex)
{ {
@@ -79,18 +74,6 @@ public abstract class AbstractDelayedYamlFileReader<T extends StorageObject> imp
Bukkit.getLogger().log(Level.SEVERE, "The file " + file.toString() + " is broken, it has been renamed to " + broken.toString(), ex.getCause()); Bukkit.getLogger().log(Level.SEVERE, "The file " + file.toString() + " is broken, it has been renamed to " + broken.toString(), ex.getCause());
} }
} }
catch (IOException ex)
{
onException(ex);
if (ess.getSettings() == null || ess.getSettings().isDebug())
{
Bukkit.getLogger().log(Level.INFO, "File not found: " + file.toString());
}
}
finally
{
lock.unlock();
}
} }
public abstract void onSuccess(T object); public abstract void onSuccess(T object);

View File

@@ -2,7 +2,6 @@ package net.ess3.storage;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level; import java.util.logging.Level;
@@ -25,17 +24,16 @@ public abstract class AbstractDelayedYamlFileWriter implements Runnable
ess.getPlugin().scheduleAsyncDelayedTask(this); ess.getPlugin().scheduleAsyncDelayedTask(this);
} }
public abstract File getFile() throws IOException; public abstract File getFile();
public abstract StorageObject getObject(); public abstract StorageObject getObject();
@Override @Override
public void run() public void run()
{ {
lock.lock(); final File file = getFile();
try synchronized (file)
{ {
final File file = getFile();
PrintWriter pw = null; PrintWriter pw = null;
try try
{ {
@@ -61,14 +59,6 @@ public abstract class AbstractDelayedYamlFileWriter implements Runnable
} }
} }
} }
catch (IOException ex)
{
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
}
finally
{
lock.unlock();
}
} }
public abstract void onFinish(); public abstract void onFinish();

View File

@@ -4,6 +4,8 @@ import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level; import java.util.logging.Level;
import net.ess3.api.IEssentials; import net.ess3.api.IEssentials;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@@ -17,11 +19,14 @@ public abstract class AsyncStorageObjectHolder<T extends StorageObject> implemen
private final transient StorageObjectDataWriter writer; private final transient StorageObjectDataWriter writer;
private final transient StorageObjectDataReader reader; private final transient StorageObjectDataReader reader;
private final transient AtomicBoolean loaded = new AtomicBoolean(false); private final transient AtomicBoolean loaded = new AtomicBoolean(false);
private volatile long savetime = 0;
private final transient File file;
public AsyncStorageObjectHolder(final IEssentials ess, final Class<T> clazz) public AsyncStorageObjectHolder(final IEssentials ess, final Class<T> clazz, final File file)
{ {
this.ess = ess; this.ess = ess;
this.clazz = clazz; this.clazz = clazz;
this.file = file;
writer = new StorageObjectDataWriter(); writer = new StorageObjectDataWriter();
reader = new StorageObjectDataReader(); reader = new StorageObjectDataReader();
try try
@@ -53,9 +58,9 @@ public abstract class AsyncStorageObjectHolder<T extends StorageObject> implemen
@Override @Override
public void queueSave() public void queueSave()
{ {
writer.schedule(); ess.getStorageQueue().queue(this);
} }
@Override @Override
public void onReload() public void onReload()
{ {
@@ -66,13 +71,42 @@ public abstract class AsyncStorageObjectHolder<T extends StorageObject> implemen
{ {
reader.schedule(instant); reader.schedule(instant);
} }
public abstract void finishRead();
public abstract void finishWrite();
public abstract File getStorageFile() throws IOException;
@Override
public String toString()
{
return file.getAbsolutePath();
}
public abstract void finishRead();
public abstract void finishWrite();
public StorageQueue.RequestState getRequestState(long timestamp)
{
if (savetime == 0 || savetime < timestamp || (timestamp < 0 && savetime > 0))
{
final long now = System.nanoTime();
if (Math.abs(now - savetime) < StorageQueue.DELAY)
{
return StorageQueue.RequestState.REQUEUE;
}
else
{
savetime = System.nanoTime();
return StorageQueue.RequestState.SCHEDULE;
}
}
else
{
return StorageQueue.RequestState.FINISHED;
}
}
Runnable getFileWriter()
{
return writer;
}
private class StorageObjectDataWriter extends AbstractDelayedYamlFileWriter private class StorageObjectDataWriter extends AbstractDelayedYamlFileWriter
{ {
@@ -82,9 +116,9 @@ public abstract class AsyncStorageObjectHolder<T extends StorageObject> implemen
} }
@Override @Override
public File getFile() throws IOException public File getFile()
{ {
return getStorageFile(); return file;
} }
@Override @Override
@@ -109,9 +143,9 @@ public abstract class AsyncStorageObjectHolder<T extends StorageObject> implemen
} }
@Override @Override
public File onStart() throws IOException public File onStart()
{ {
return getStorageFile(); return file;
} }
@Override @Override
@@ -122,6 +156,7 @@ public abstract class AsyncStorageObjectHolder<T extends StorageObject> implemen
data = object; data = object;
} }
loaded.set(true); loaded.set(true);
finishRead();
} }
@Override @Override

View File

@@ -0,0 +1,141 @@
package net.ess3.storage;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.ess3.api.IPlugin;
public class StorageQueue implements Runnable
{
private DelayQueue<WriteRequest> queue = new DelayQueue<WriteRequest>();
public final static long DELAY = TimeUnit.NANOSECONDS.convert(1, TimeUnit.SECONDS);
private final AtomicBoolean enabled = new AtomicBoolean(false);
private final transient Object lock = new Object();
private final IPlugin plugin;
public StorageQueue(IPlugin plugin)
{
this.plugin = plugin;
}
@Override
public void run()
{
synchronized (lock)
{
List<WriteRequest> requests = new ArrayList<WriteRequest>();
while (enabled.get() || !queue.isEmpty())
{
try
{
queue.drainTo(requests);
for (WriteRequest request : requests)
{
RequestState state = request.getRequestState();
if (state == RequestState.REQUEUE)
{
queue.add(request);
continue;
}
if (state == RequestState.SCHEDULE)
{
plugin.scheduleAsyncDelayedTask(request.getRunnable());
}
}
requests.clear();
Thread.sleep(100);
}
catch (InterruptedException ex)
{
continue;
}
}
}
}
public void queue(AsyncStorageObjectHolder objectHolder)
{
if (!enabled.get())
{
plugin.getLogger().log(Level.SEVERE,
"File " + objectHolder.toString() + " is queued for saving, while the queue is disabled. It's possible that it will not be saved!",
new RuntimeException());
}
queue.add(new WriteRequest(objectHolder));
}
private void startThread()
{
synchronized (lock)
{
plugin.scheduleAsyncDelayedTask(this);
}
}
public void setEnabled(boolean enabled)
{
if (this.enabled.getAndSet(enabled) != enabled && enabled)
{
startThread();
}
}
private class WriteRequest implements Delayed
{
private final AsyncStorageObjectHolder objectHolder;
private final long timestamp;
public WriteRequest(AsyncStorageObjectHolder objectHolder)
{
this.objectHolder = objectHolder;
this.timestamp = System.nanoTime();
}
@Override
public long getDelay(final TimeUnit tu)
{
if (tu == TimeUnit.NANOSECONDS)
{
final long now = System.nanoTime();
return DELAY - Math.abs(now - timestamp);
}
else
{
return tu.convert(getDelay(TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS);
}
}
@Override
public int compareTo(final Delayed t)
{
final long a = getDelay(TimeUnit.NANOSECONDS);
final long b = t.getDelay(TimeUnit.NANOSECONDS);
return a < b ? -1 : a == b ? 0 : 1;
}
public RequestState getRequestState()
{
return objectHolder.getRequestState(timestamp);
}
public Runnable getRunnable()
{
return objectHolder.getFileWriter();
}
}
public enum RequestState
{
REQUEUE,
SCHEDULE,
FINISHED
}
}

View File

@@ -54,7 +54,7 @@ public class User extends UserBase implements IUser
private AtomicBoolean gotMailInfo = new AtomicBoolean(false); private AtomicBoolean gotMailInfo = new AtomicBoolean(false);
private WeakReference<Player> playerCache; private WeakReference<Player> playerCache;
public User(final OfflinePlayer base, final IEssentials ess) public User(final OfflinePlayer base, final IEssentials ess) throws InvalidNameException
{ {
super(base, ess); super(base, ess);
teleport = new Teleport(this, ess); teleport = new Teleport(this, ess);

View File

@@ -29,9 +29,9 @@ public abstract class UserBase extends AsyncStorageObjectHolder<UserData> implem
@Delegate @Delegate
protected final OfflinePlayer offlinePlayer; protected final OfflinePlayer offlinePlayer;
public UserBase(final OfflinePlayer base, final IEssentials ess) public UserBase(final OfflinePlayer base, final IEssentials ess) throws InvalidNameException
{ {
super(ess, UserData.class); super(ess, UserData.class, ess.getUserMap().getUserFile(base.getName()));
this.offlinePlayer = base; this.offlinePlayer = base;
onReload(); onReload();
} }
@@ -160,19 +160,6 @@ public abstract class UserBase extends AsyncStorageObjectHolder<UserData> implem
throw new UnsupportedOperationException("Not supported yet."); throw new UnsupportedOperationException("Not supported yet.");
} }
@Override
public File getStorageFile() throws IOException
{
try
{
return ess.getUserMap().getUserFile(getName());
}
catch (InvalidNameException ex)
{
throw new IOException(ex.getMessage(), ex);
}
}
public long getTimestamp(final UserData.TimestampType name) public long getTimestamp(final UserData.TimestampType name)
{ {
return getData().getTimestamp(name); return getData().getTimestamp(name);

View File

@@ -90,12 +90,7 @@ public class UserMap extends StorageObjectMap<IUser> implements IUserMap
@Override @Override
public IUser getUser(final Player player) public IUser getUser(final Player player)
{ {
IUser user = getObject(player.getName()); return getObject(player.getName());
if (user == null)
{
user = new User(player, ess);
}
return user;
} }
@Override @Override

View File

@@ -1,7 +1,6 @@
package net.ess3.antibuild; package net.ess3.antibuild;
import java.io.File; import java.io.File;
import java.io.IOException;
import net.ess3.api.IEssentials; import net.ess3.api.IEssentials;
import net.ess3.settings.antibuild.AntiBuild; import net.ess3.settings.antibuild.AntiBuild;
import net.ess3.storage.AsyncStorageObjectHolder; import net.ess3.storage.AsyncStorageObjectHolder;
@@ -10,13 +9,7 @@ public class AntiBuildHolder extends AsyncStorageObjectHolder<AntiBuild>
{ {
public AntiBuildHolder(final IEssentials ess) public AntiBuildHolder(final IEssentials ess)
{ {
super(ess, AntiBuild.class); super(ess, AntiBuild.class, new File(ess.getPlugin().getDataFolder(), "protect.yml"));
}
@Override
public File getStorageFile() throws IOException
{
return new File(ess.getPlugin().getDataFolder(), "protect.yml");
} }
@Override @Override

View File

@@ -1,7 +1,6 @@
package net.ess3.geoip; package net.ess3.geoip;
import java.io.File; import java.io.File;
import java.io.IOException;
import net.ess3.api.IEssentials; import net.ess3.api.IEssentials;
import net.ess3.settings.geoip.GeoIP; import net.ess3.settings.geoip.GeoIP;
import net.ess3.storage.AsyncStorageObjectHolder; import net.ess3.storage.AsyncStorageObjectHolder;
@@ -14,17 +13,11 @@ public class ConfigHolder extends AsyncStorageObjectHolder<GeoIP>
public ConfigHolder(final IEssentials ess, final Plugin geoip) public ConfigHolder(final IEssentials ess, final Plugin geoip)
{ {
super(ess, GeoIP.class); super(ess, GeoIP.class, new File(geoip.getDataFolder(), "config.yml"));
this.geoip = geoip; this.geoip = geoip;
onReload(true); onReload(true);
} }
@Override
public File getStorageFile() throws IOException
{
return new File(geoip.getDataFolder(), "config.yml");
}
@Override @Override
public void finishRead() public void finishRead()
{ {

View File

@@ -1,7 +1,6 @@
package net.ess3.protect; package net.ess3.protect;
import java.io.File; import java.io.File;
import java.io.IOException;
import net.ess3.api.IEssentials; import net.ess3.api.IEssentials;
import net.ess3.settings.protect.Protect; import net.ess3.settings.protect.Protect;
import net.ess3.storage.AsyncStorageObjectHolder; import net.ess3.storage.AsyncStorageObjectHolder;
@@ -11,13 +10,7 @@ public class ProtectHolder extends AsyncStorageObjectHolder<Protect>
{ {
public ProtectHolder(final IEssentials ess) public ProtectHolder(final IEssentials ess)
{ {
super(ess, Protect.class); super(ess, Protect.class, new File(ess.getPlugin().getDataFolder(), "protect.yml"));
}
@Override
public File getStorageFile() throws IOException
{
return new File(ess.getPlugin().getDataFolder(), "protect.yml");
} }
@Override @Override

View File

@@ -1,7 +1,6 @@
package net.ess3.signs; package net.ess3.signs;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.*; import java.util.*;
import net.ess3.api.IEssentials; import net.ess3.api.IEssentials;
import net.ess3.storage.AsyncStorageObjectHolder; import net.ess3.storage.AsyncStorageObjectHolder;
@@ -16,7 +15,7 @@ public class SignsConfigHolder extends AsyncStorageObjectHolder<SignsConfig>
public SignsConfigHolder(final IEssentials ess, final Plugin plugin) public SignsConfigHolder(final IEssentials ess, final Plugin plugin)
{ {
super(ess, SignsConfig.class); super(ess, SignsConfig.class, new File(plugin.getDataFolder(), "config.yml"));
this.plugin = plugin; this.plugin = plugin;
onReload(); onReload();
final Map<String, Boolean> signs = getData().getSigns(); final Map<String, Boolean> signs = getData().getSigns();
@@ -44,12 +43,6 @@ public class SignsConfigHolder extends AsyncStorageObjectHolder<SignsConfig>
queueSave(); queueSave();
} }
@Override
public File getStorageFile() throws IOException
{
return new File(plugin.getDataFolder(), "config.yml");
}
public Set<EssentialsSign> getEnabledSigns() public Set<EssentialsSign> getEnabledSigns()
{ {
return enabledSigns; return enabledSigns;