-
Notifications
You must be signed in to change notification settings - Fork 0
Holder Implementation
The terminal builder method you call determines the holder implementation. All three expose the
same ConfigHolder API; createAsync() returns the wider AsyncConfigHolder which adds
non-blocking *Async variants.
| Method | Where work runs | Thread safety | Best fit |
|---|---|---|---|
create() |
Calling thread, inline | Confine to one thread (e.g. the server thread) | Regular runtime config |
createAsync() |
Shared config worker thread | Safe from any thread | Config accessed from multiple threads |
createImmutable() |
Frozen at build time | Read-only, safe from any thread | Startup-only config |
// Single-threaded — all operations run on whichever thread calls them
ConfigHolder<MyModConfig> simple = EasyConfig.holder(MyModConfig.class)
.modId("mymod")
.create();
// Thread-safe — operations are submitted to the worker; blocking callers wait
AsyncConfigHolder<MyModConfig> async = EasyConfig.holder(MyModConfig.class)
.modId("mymod")
.createAsync();
// Immutable — loaded once during create; update and reset are refused
ConfigHolder<MyModConfig> immutable = EasyConfig.holder(MyModConfig.class)
.modId("mymod")
.createImmutable();Async: the blocking methods (load, save, update, updateAndSave) submit work to the
worker and join. Calling them from inside a config hook or lifecycle listener will deadlock
and is reported as ConfigError.BLOCKING_CALL_ON_CONFIG_THREAD. Use the *Async variants
(loadAsync, saveAsync, updateAsync, updateAndSaveAsync) when you are already on the config
thread or simply do not want to block. Those methods are exclusive to AsyncConfigHolder.
Immutable: update, reset, and their variants are refused through the update failure policy
— they throw under STRICT and return a rejected UpdateResult under FALLBACK. load and
save still work: a reload replaces the published state wholesale.