Small performance improvements (resolving world-ids and sql-querys)

This commit is contained in:
Lukas Rieger (Blue) 2022-08-09 22:35:21 +02:00
parent 057d25bd15
commit 44906f889b
No known key found for this signature in database
GPG Key ID: 2D09EC5ED2687FF2
2 changed files with 53 additions and 40 deletions

View File

@ -49,6 +49,7 @@
import de.bluecolored.bluemap.core.world.World;
import org.apache.commons.io.FileUtils;
import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.gson.GsonConfigurationLoader;
import org.spongepowered.configurate.loader.HeaderMode;
@ -59,6 +60,7 @@
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
/**
@ -81,13 +83,13 @@ public BlueMapService(ServerInterface serverInterface, BlueMapConfigProvider con
this.serverInterface = serverInterface;
this.configs = configProvider;
this.worldIds = new HashMap<>();
this.worldIds = new ConcurrentHashMap<>();
this.storages = new HashMap<>();
StateDumper.global().register(this);
}
public synchronized String getWorldId(Path worldFolder) throws IOException {
public String getWorldId(Path worldFolder) throws IOException {
// fast-path
String id = worldIds.get(worldFolder);
if (id != null) return id;
@ -102,22 +104,29 @@ public synchronized String getWorldId(Path worldFolder) throws IOException {
id = worldIds.get(worldFolder);
if (id != null) return id;
// now we can be sure it wasn't loaded yet .. load
synchronized (this) {
// check again if another thread has already added the world
id = worldIds.get(worldFolder);
if (id != null) return id;
Path idFile = worldFolder.resolve("bluemap.id");
if (!Files.exists(idFile)) {
id = this.serverInterface.getWorld(worldFolder)
.flatMap(ServerWorld::getId)
.orElse(UUID.randomUUID().toString());
Files.writeString(idFile, id, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
Logger.global.logDebug("Loading world id for '" + worldFolder + "'...");
// now we can be sure it wasn't loaded yet .. load
Path idFile = worldFolder.resolve("bluemap.id");
if (!Files.exists(idFile)) {
id = this.serverInterface.getWorld(worldFolder)
.flatMap(ServerWorld::getId)
.orElse(UUID.randomUUID().toString());
Files.writeString(idFile, id, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
worldIds.put(worldFolder, id);
return id;
}
id = Files.readString(idFile);
worldIds.put(worldFolder, id);
return id;
}
id = Files.readString(idFile);
worldIds.put(worldFolder, id);
return id;
}
public synchronized void createOrUpdateWebApp(boolean force) throws ConfigurationException {
@ -217,12 +226,13 @@ private synchronized void loadWorldsAndMaps() throws ConfigurationException, Int
maps.put(id, map);
// load marker-config by converting it first from hocon to json and then loading it with MarkerGson
if (!mapConfig.getMarkerSets().empty()) {
ConfigurationNode markerSetNode = mapConfig.getMarkerSets();
if (markerSetNode != null && !markerSetNode.empty()) {
String markerJson = GsonConfigurationLoader.builder()
.headerMode(HeaderMode.NONE)
.lenient(false)
.indent(0)
.buildAndSaveString(mapConfig.getMarkerSets());
.buildAndSaveString(markerSetNode);
Gson gson = MarkerGson.addAdapters(new GsonBuilder())
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES)
.create();
@ -257,6 +267,8 @@ public synchronized Storage getStorage(String storageId) throws ConfigurationExc
"You will either need to define that storage, or change the map-config to use a storage-config that exists.");
}
Logger.global.logInfo("Initializing Storage: '" + storageId + "' (Type: " + storageConfig.getStorageType() + ")");
storage = storageConfig.createStorage();
storage.initialize();
} catch (Exception ex) {

View File

@ -538,34 +538,28 @@ private void recoveringConnection(ConnectionConsumer action, int tries) throws S
@SuppressWarnings("SameParameterValue")
private <R> R recoveringConnection(ConnectionFunction<R> action, int tries) throws SQLException, IOException {
SQLException sqlException = null;
for (int i = 0; i < tries; i++) {
try (Connection connection = dataSource.getConnection()) {
connection.setAutoCommit(false);
R result;
try {
result = action.apply(connection);
connection.commit();
} catch (SQLRecoverableException ex) {
connection.rollback();
if (sqlException == null) {
sqlException = ex;
} else {
sqlException.addSuppressed(ex);
try {
for (int i = 0; i < tries; i++) {
try (Connection connection = dataSource.getConnection()) {
R result;
try {
result = action.apply(connection);
connection.commit();
return result;
} catch (SQLRecoverableException ex) {
if (sqlException == null) {
sqlException = ex;
} else {
sqlException.addSuppressed(ex);
}
}
continue;
} catch (SQLException | RuntimeException ex) {
connection.rollback();
throw ex;
}
connection.setAutoCommit(true);
return result;
} catch (SQLException | IOException | RuntimeException ex) {
if (sqlException != null)
ex.addSuppressed(sqlException);
throw ex;
}
} catch (SQLException | IOException | RuntimeException ex) {
if (sqlException != null)
ex.addSuppressed(sqlException);
throw ex;
}
assert sqlException != null; // should never be null if we end up here
@ -680,9 +674,16 @@ private DataSource createDataSource(String dbUrl, String user, String password,
private DataSource createDataSource(ConnectionFactory connectionFactory) {
PoolableConnectionFactory poolableConnectionFactory =
new PoolableConnectionFactory(connectionFactory, null);
new PoolableConnectionFactory(() -> {
Logger.global.logDebug("Creating new SQL-Connection...");
return connectionFactory.createConnection();
}, null);
poolableConnectionFactory.setPoolStatements(true);
poolableConnectionFactory.setMaxOpenPreparedStatements(20);
poolableConnectionFactory.setDefaultAutoCommit(false);
poolableConnectionFactory.setAutoCommitOnReturn(false);
poolableConnectionFactory.setRollbackOnReturn(true);
poolableConnectionFactory.setFastFailValidation(true);
GenericObjectPoolConfig<PoolableConnection> objectPoolConfig = new GenericObjectPoolConfig<>();
objectPoolConfig.setMinIdle(1);