Skip to content

Commit bca3359

Browse files
committed
Add data.sync option that loads the data on the main thread
(cherry picked from commit c7d2a94)
1 parent e667fa7 commit bca3359

3 files changed

Lines changed: 37 additions & 3 deletions

File tree

src/main/java/me/wolfyscript/customcrafting/configs/DataSettings.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public class DataSettings {
3939
private static final String PRINT_STACKTRACE = "print_stacktrace";
4040
private static final String BUKKIT_VERSION = "bukkit_version";
4141
private static final String CONFIG_VERSION = "version";
42+
private static final String SYNC = "sync";
4243

4344
private final ConfigurationSection section;
4445

@@ -56,6 +57,10 @@ private Pair<Long, TimeUnit> timeout(ConfigurationSection section, String key) {
5657
Objects.requireNonNullElse(TimeUnit.valueOf(section.getString(key + ".unit")), TimeUnit.SECONDS));
5758
}
5859

60+
public boolean sync() {
61+
return section.getBoolean(SYNC, false);
62+
}
63+
5964
public boolean printPending() {
6065
return section.getBoolean(PRINT_PENDING);
6166
}

src/main/java/me/wolfyscript/customcrafting/handlers/LocalStorageLoader.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import me.wolfyscript.utilities.util.NamespacedKey;
4444
import me.wolfyscript.utilities.util.Pair;
4545
import org.apache.commons.lang3.time.StopWatch;
46+
import org.bukkit.Bukkit;
4647

4748
import java.io.File;
4849
import java.io.IOException;
@@ -146,6 +147,9 @@ public void load() {
146147
api.getConsole().info("- - - - [Local Storage] - - - -");
147148
int processors = Math.min(Runtime.getRuntime().availableProcessors(), dataSettings.maxProcessors());
148149
customCrafting.getLogger().info(PREFIX + "Using " + processors + " threads");
150+
if (dataSettings.sync()) {
151+
customCrafting.getLogger().info(PREFIX + "Loading data synchronously");
152+
}
149153
executor = Executors.newWorkStealingPool(processors);
150154
api.getConsole().info(PREFIX + "Looking through data folder...");
151155
String[] dirs = DATA_FOLDER.list();
@@ -416,7 +420,7 @@ private void checkDependenciesAndRegister(CustomRecipe<?> recipe) {
416420
/**
417421
* Used to load data & cache the loaded, skipped errors & already existing keys.
418422
*/
419-
private abstract static class DataLoader {
423+
private abstract class DataLoader {
420424

421425
protected final String[] dirs;
422426

@@ -426,6 +430,28 @@ private DataLoader(String[] dirs) {
426430

427431
protected abstract void load();
428432

433+
protected void executeTask(Runnable runnable) {
434+
if (dataSettings.sync()) {
435+
if (Bukkit.isPrimaryThread()) {
436+
// This option will cause the task to run on the main thread! Required for plugins like MMOItems
437+
runnable.run();
438+
} else {
439+
// The LocalStorageLoader was not called from the main thread.
440+
// Not sure what to do in this case... maybe a hacky Future thingy will work
441+
try {
442+
Bukkit.getScheduler().callSyncMethod(customCrafting, () -> {
443+
runnable.run();
444+
return true;
445+
}).get(dataSettings.timeoutLoading().getKey(), dataSettings.timeoutLoading().getValue());
446+
} catch (InterruptedException | ExecutionException | TimeoutException e) {
447+
customCrafting.getLogger().log(Level.SEVERE, "Error while loading recipe ", e);
448+
}
449+
}
450+
} else {
451+
executor.execute(runnable);
452+
}
453+
}
454+
429455
}
430456

431457
private class NewDataLoader extends DataLoader {
@@ -448,7 +474,7 @@ private void loadRecipesInNamespace(String namespace) {
448474
if (isValidFile(file.toFile())) return FileVisitResult.CONTINUE;
449475
final var namespacedKey = keyFromFile(namespace, relative);
450476
if (isReplaceData() || !customCrafting.getRegistries().getRecipes().has(namespacedKey)) {
451-
executor.execute(() -> {
477+
executeTask(() -> {
452478
try {
453479
var injectableValues = new InjectableValues.Std();
454480
injectableValues.addValue("key", namespacedKey);
@@ -533,7 +559,7 @@ protected void loadOldOrLegacyRecipeFiles(RecipeLoader<?> loader, List<File> fil
533559
if (isValidFile(file)) continue;
534560
var namespacedKey = new NamespacedKey(customCrafting, namespace + "/" + name.substring(0, name.lastIndexOf(".")));
535561
if (!customCrafting.getRegistries().getRecipes().has(namespacedKey)) {
536-
executor.execute(() -> {
562+
executeTask(() -> {
537563
try {
538564
CustomRecipe<?> recipe = loader.getInstance(namespacedKey, objectMapper.readTree(file));
539565
checkDependenciesAndRegister(recipe);

src/main/resources/config.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ data:
8080
# Specifies the maximum number of processors to use for loading the data
8181
# Uses either all available processors, or the specified count, whichever is smaller
8282
max_processors: 64
83+
# When set true, uses the sync scheduler to load the items & recipes.
84+
# Data is then loaded sequentially and not parallel across multiple cores (ignores 'max_processors')
85+
sync: false
8386
# Specifies if it should print details about why the recipes are pending.
8487
# Recipes are mostly pending because of dependencies, and are validated once a dependency is done loading its data.
8588
# Usually not required as pending recipes not validated are marked as 'invalid' after a given timeout (see 'data.timeout.pending').

0 commit comments

Comments
 (0)