mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-04-19 17:16:53 -04:00
Throttle calls to Settings.save()
This commit is contained in:
@@ -136,6 +136,7 @@ class ExitUtil {
|
||||
return;
|
||||
} else {
|
||||
settings.setNumTrayNotifications(settings.getNumTrayNotifications() - 1);
|
||||
settings.save();
|
||||
}
|
||||
final Runnable notificationCmd;
|
||||
if (SystemUtils.IS_OS_MAC_OSX) {
|
||||
|
||||
@@ -40,6 +40,7 @@ import javafx.beans.binding.BooleanBinding;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ListChangeListener.Change;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
@@ -94,6 +95,9 @@ public class MainController extends LocalizedFXMLViewController {
|
||||
this.changePasswordController = changePasswordController;
|
||||
this.settingsController = settingsController;
|
||||
this.vaults = FXCollections.observableList(settings.getDirectories());
|
||||
this.vaults.addListener((Change<? extends Vault> c) -> {
|
||||
settings.save();
|
||||
});
|
||||
|
||||
// derived bindings:
|
||||
this.isShowingSettings = activeController.isEqualTo(settingsController.get());
|
||||
|
||||
@@ -59,9 +59,9 @@ public class SettingsController extends LocalizedFXMLViewController {
|
||||
useIpv6Checkbox.setSelected(SystemUtils.IS_OS_WINDOWS && settings.shouldUseIpv6());
|
||||
versionLabel.setText(String.format(localization.getString("settings.version.label"), applicationVersion().orElse("SNAPSHOT")));
|
||||
|
||||
EasyBind.subscribe(checkForUpdatesCheckbox.selectedProperty(), settings::setCheckForUpdatesEnabled);
|
||||
EasyBind.subscribe(checkForUpdatesCheckbox.selectedProperty(), this::checkForUpdateDidChange);
|
||||
EasyBind.subscribe(portField.textProperty(), this::portDidChange);
|
||||
EasyBind.subscribe(useIpv6Checkbox.selectedProperty(), settings::setUseIpv6);
|
||||
EasyBind.subscribe(useIpv6Checkbox.selectedProperty(), this::useIpv6DidChange);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,21 +73,30 @@ public class SettingsController extends LocalizedFXMLViewController {
|
||||
return Optional.ofNullable(getClass().getPackage().getImplementationVersion());
|
||||
}
|
||||
|
||||
private void checkForUpdateDidChange(Boolean newValue) {
|
||||
settings.setCheckForUpdatesEnabled(newValue);
|
||||
settings.save();
|
||||
}
|
||||
|
||||
private void portDidChange(String newValue) {
|
||||
try {
|
||||
int port = Integer.parseInt(newValue);
|
||||
if (port < Settings.MIN_PORT) {
|
||||
if (port < Settings.MIN_PORT || port > Settings.MAX_PORT) {
|
||||
settings.setPort(Settings.DEFAULT_PORT);
|
||||
} else if (port < Settings.MAX_PORT) {
|
||||
settings.setPort(port);
|
||||
} else {
|
||||
portField.setText(String.valueOf(Settings.MAX_PORT));
|
||||
settings.setPort(port);
|
||||
settings.save();
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
portField.setText(String.valueOf(Settings.DEFAULT_PORT));
|
||||
}
|
||||
}
|
||||
|
||||
private void useIpv6DidChange(Boolean newValue) {
|
||||
settings.setUseIpv6(newValue);
|
||||
settings.save();
|
||||
}
|
||||
|
||||
private void filterNumericKeyEvents(KeyEvent t) {
|
||||
if (t.getCharacter() == null || t.getCharacter().length() == 0) {
|
||||
return;
|
||||
|
||||
@@ -48,26 +48,11 @@ public class Settings implements Serializable {
|
||||
/**
|
||||
* Package-private constructor; use {@link SettingsProvider}.
|
||||
*/
|
||||
Settings() {
|
||||
this.saveCmd = s -> {
|
||||
};
|
||||
}
|
||||
|
||||
private Settings(Consumer<Settings> saveCmd) {
|
||||
Settings(Consumer<Settings> saveCmd) {
|
||||
this.saveCmd = saveCmd;
|
||||
}
|
||||
|
||||
Settings withSaveCmd(Consumer<Settings> saveCmd) {
|
||||
final Settings result = new Settings(saveCmd);
|
||||
result.directories = this.directories;
|
||||
result.checkForUpdatesEnabled = this.checkForUpdatesEnabled;
|
||||
result.port = this.port;
|
||||
result.useIpv6 = this.useIpv6;
|
||||
result.numTrayNotifications = this.numTrayNotifications;
|
||||
return result;
|
||||
}
|
||||
|
||||
private void save() {
|
||||
public void save() {
|
||||
saveCmd.accept(this);
|
||||
}
|
||||
|
||||
@@ -82,7 +67,6 @@ public class Settings implements Serializable {
|
||||
|
||||
public void setDirectories(List<Vault> directories) {
|
||||
this.directories = directories;
|
||||
save();
|
||||
}
|
||||
|
||||
public boolean isCheckForUpdatesEnabled() {
|
||||
@@ -92,7 +76,6 @@ public class Settings implements Serializable {
|
||||
|
||||
public void setCheckForUpdatesEnabled(boolean checkForUpdatesEnabled) {
|
||||
this.checkForUpdatesEnabled = checkForUpdatesEnabled;
|
||||
save();
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
@@ -100,7 +83,6 @@ public class Settings implements Serializable {
|
||||
throw new IllegalArgumentException("Invalid port");
|
||||
}
|
||||
this.port = port;
|
||||
save();
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
@@ -121,7 +103,6 @@ public class Settings implements Serializable {
|
||||
|
||||
public void setUseIpv6(boolean useIpv6) {
|
||||
this.useIpv6 = useIpv6;
|
||||
save();
|
||||
}
|
||||
|
||||
public Integer getNumTrayNotifications() {
|
||||
@@ -130,7 +111,6 @@ public class Settings implements Serializable {
|
||||
|
||||
public void setNumTrayNotifications(Integer numTrayNotifications) {
|
||||
this.numTrayNotifications = numTrayNotifications;
|
||||
save();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user