|
@@ -16,6 +16,12 @@ import java.nio.file.FileSystems;
|
|
|
import java.nio.file.Files;
|
|
|
import java.nio.file.Path;
|
|
|
import java.nio.file.StandardOpenOption;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.concurrent.Executors;
|
|
|
+import java.util.concurrent.ScheduledExecutorService;
|
|
|
+import java.util.concurrent.ScheduledFuture;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.concurrent.atomic.AtomicReference;
|
|
|
|
|
|
import javax.inject.Inject;
|
|
|
import javax.inject.Named;
|
|
@@ -34,6 +40,7 @@ public class SettingsProvider implements Provider<Settings> {
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(SettingsProvider.class);
|
|
|
private static final Path SETTINGS_DIR;
|
|
|
private static final String SETTINGS_FILE = "settings.json";
|
|
|
+ private static final long SAVE_DELAY_MS = 1000;
|
|
|
|
|
|
static {
|
|
|
final String appdata = System.getenv("APPDATA");
|
|
@@ -52,6 +59,8 @@ public class SettingsProvider implements Provider<Settings> {
|
|
|
}
|
|
|
|
|
|
private final ObjectMapper objectMapper;
|
|
|
+ private final ScheduledExecutorService saveScheduler = Executors.newSingleThreadScheduledExecutor();
|
|
|
+ private final AtomicReference<ScheduledFuture<?>> scheduledSaveCmd = new AtomicReference<>();
|
|
|
|
|
|
@Inject
|
|
|
public SettingsProvider(@Named("VaultJsonMapper") ObjectMapper objectMapper) {
|
|
@@ -69,23 +78,33 @@ public class SettingsProvider implements Provider<Settings> {
|
|
|
|
|
|
@Override
|
|
|
public Settings get() {
|
|
|
- Settings settings = null;
|
|
|
+ final Settings settings = new Settings(this::scheduleSave);
|
|
|
try {
|
|
|
final Path settingsPath = getSettingsPath();
|
|
|
final InputStream in = Files.newInputStream(settingsPath, StandardOpenOption.READ);
|
|
|
- settings = objectMapper.readValue(in, Settings.class);
|
|
|
+ objectMapper.readerForUpdating(settings).readValue(in);
|
|
|
LOG.info("Settings loaded from " + settingsPath);
|
|
|
} catch (IOException e) {
|
|
|
LOG.info("Failed to load settings, creating new one.");
|
|
|
- settings = new Settings();
|
|
|
}
|
|
|
- return settings.withSaveCmd(this::save);
|
|
|
+ return settings;
|
|
|
}
|
|
|
|
|
|
- private void save(Settings settings) {
|
|
|
+ private void scheduleSave(Settings settings) {
|
|
|
if (settings == null) {
|
|
|
return;
|
|
|
}
|
|
|
+ ScheduledFuture<?> saveCmd = saveScheduler.schedule(() -> {
|
|
|
+ this.save(settings);
|
|
|
+ } , SAVE_DELAY_MS, TimeUnit.MILLISECONDS);
|
|
|
+ ScheduledFuture<?> previousSaveCmd = scheduledSaveCmd.getAndSet(saveCmd);
|
|
|
+ if (previousSaveCmd != null) {
|
|
|
+ previousSaveCmd.cancel(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void save(Settings settings) {
|
|
|
+ Objects.requireNonNull(settings);
|
|
|
try {
|
|
|
final Path settingsPath = getSettingsPath();
|
|
|
Files.createDirectories(settingsPath.getParent());
|