save and backup wallet files once per 5 minutes on polling

This commit is contained in:
woodser 2024-12-27 10:17:18 -05:00
parent 0462ddc273
commit 9e95de2d7e
3 changed files with 39 additions and 16 deletions

View file

@ -901,6 +901,7 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
} }
} }
@Override
public void requestSaveWallet() { public void requestSaveWallet() {
// save wallet off main thread // save wallet off main thread
@ -911,6 +912,7 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
}, getId()); }, getId());
} }
@Override
public void saveWallet() { public void saveWallet() {
synchronized (walletLock) { synchronized (walletLock) {
if (!walletExists()) { if (!walletExists()) {
@ -2675,7 +2677,7 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
pollInProgress = false; pollInProgress = false;
} }
} }
requestSaveWallet(); saveWalletWithDelay();
} }
} }

View file

@ -30,11 +30,13 @@ public abstract class XmrWalletBase {
// constants // constants
public static final int SYNC_PROGRESS_TIMEOUT_SECONDS = 120; public static final int SYNC_PROGRESS_TIMEOUT_SECONDS = 120;
public static final int DIRECT_SYNC_WITHIN_BLOCKS = 100; public static final int DIRECT_SYNC_WITHIN_BLOCKS = 100;
public static final int SAVE_WALLET_DELAY_SECONDS = 300;
// inherited // inherited
protected MoneroWallet wallet; protected MoneroWallet wallet;
@Getter @Getter
protected final Object walletLock = new Object(); protected final Object walletLock = new Object();
protected Timer saveWalletDelayTimer;
@Getter @Getter
protected XmrConnectionService xmrConnectionService; protected XmrConnectionService xmrConnectionService;
protected boolean wasWalletSynced; protected boolean wasWalletSynced;
@ -146,8 +148,23 @@ public abstract class XmrWalletBase {
return false; return false;
} }
protected abstract void onConnectionChanged(MoneroRpcConnection connection); public void saveWalletWithDelay() {
// delay writing to disk to avoid frequent write operations
if (saveWalletDelayTimer == null) {
saveWalletDelayTimer = UserThread.runAfter(() -> {
requestSaveWallet();
UserThread.execute(() -> saveWalletDelayTimer = null);
}, SAVE_WALLET_DELAY_SECONDS, TimeUnit.SECONDS);
}
}
// --------------------------------- ABSTRACT -----------------------------
public abstract void saveWallet();
public abstract void requestSaveWallet();
protected abstract void onConnectionChanged(MoneroRpcConnection connection);
// ------------------------------ PRIVATE HELPERS ------------------------- // ------------------------------ PRIVATE HELPERS -------------------------

View file

@ -245,16 +245,20 @@ public class XmrWalletService extends XmrWalletBase {
return user.getWalletCreationDate(); return user.getWalletCreationDate();
} }
public void saveMainWallet() { @Override
saveMainWallet(!(Utilities.isWindows() && wallet != null)); public void saveWallet() {
saveWallet(!(Utilities.isWindows() && wallet != null));
} }
public void saveMainWallet(boolean backup) { public void saveWallet(boolean backup) {
synchronized (walletLock) {
saveWallet(getWallet(), backup); saveWallet(getWallet(), backup);
} }
}
public void requestSaveMainWallet() { @Override
ThreadUtils.submitToPool(() -> saveMainWallet()); // save wallet off main thread public void requestSaveWallet() {
ThreadUtils.submitToPool(() -> saveWallet()); // save wallet off main thread
} }
public boolean isWalletAvailable() { public boolean isWalletAvailable() {
@ -443,7 +447,7 @@ public class XmrWalletService extends XmrWalletBase {
if (Boolean.TRUE.equals(txConfig.getRelay())) { if (Boolean.TRUE.equals(txConfig.getRelay())) {
cachedTxs.addFirst(tx); cachedTxs.addFirst(tx);
cacheWalletInfo(); cacheWalletInfo();
requestSaveMainWallet(); requestSaveWallet();
} }
return tx; return tx;
} }
@ -453,7 +457,7 @@ public class XmrWalletService extends XmrWalletBase {
public String relayTx(String metadata) { public String relayTx(String metadata) {
synchronized (walletLock) { synchronized (walletLock) {
String txId = wallet.relayTx(metadata); String txId = wallet.relayTx(metadata);
requestSaveMainWallet(); requestSaveWallet();
return txId; return txId;
} }
} }
@ -552,7 +556,7 @@ public class XmrWalletService extends XmrWalletBase {
// freeze outputs // freeze outputs
for (String keyImage : unfrozenKeyImages) wallet.freezeOutput(keyImage); for (String keyImage : unfrozenKeyImages) wallet.freezeOutput(keyImage);
cacheWalletInfo(); cacheWalletInfo();
requestSaveMainWallet(); requestSaveWallet();
} }
} }
@ -574,7 +578,7 @@ public class XmrWalletService extends XmrWalletBase {
// thaw outputs // thaw outputs
for (String keyImage : frozenKeyImages) wallet.thawOutput(keyImage); for (String keyImage : frozenKeyImages) wallet.thawOutput(keyImage);
cacheWalletInfo(); cacheWalletInfo();
requestSaveMainWallet(); requestSaveWallet();
} }
} }
@ -1424,14 +1428,14 @@ public class XmrWalletService extends XmrWalletBase {
HavenoUtils.havenoSetup.getWalletInitialized().set(true); HavenoUtils.havenoSetup.getWalletInitialized().set(true);
// save but skip backup on initialization // save but skip backup on initialization
saveMainWallet(false); saveWallet(false);
} catch (Exception e) { } catch (Exception e) {
if (isClosingWallet || isShutDownStarted || HavenoUtils.havenoSetup.getWalletInitialized().get()) return; // ignore if wallet closing, shut down started, or app already initialized if (isClosingWallet || isShutDownStarted || HavenoUtils.havenoSetup.getWalletInitialized().get()) return; // ignore if wallet closing, shut down started, or app already initialized
log.warn("Error initially syncing main wallet: {}", e.getMessage()); log.warn("Error initially syncing main wallet: {}", e.getMessage());
if (numSyncAttempts <= 1) { if (numSyncAttempts <= 1) {
log.warn("Failed to sync main wallet. Opening app without syncing", numSyncAttempts); log.warn("Failed to sync main wallet. Opening app without syncing", numSyncAttempts);
HavenoUtils.havenoSetup.getWalletInitialized().set(true); HavenoUtils.havenoSetup.getWalletInitialized().set(true);
saveMainWallet(false); saveWallet(false);
// reschedule to init main wallet // reschedule to init main wallet
UserThread.runAfter(() -> { UserThread.runAfter(() -> {
@ -1809,7 +1813,7 @@ public class XmrWalletService extends XmrWalletBase {
tasks.add(() -> { tasks.add(() -> {
try { try {
wallet.changePassword(oldPassword, newPassword); wallet.changePassword(oldPassword, newPassword);
saveMainWallet(); saveWallet();
} catch (Exception e) { } catch (Exception e) {
log.warn("Error changing main wallet password: " + e.getMessage() + "\n", e); log.warn("Error changing main wallet password: " + e.getMessage() + "\n", e);
throw e; throw e;
@ -2002,7 +2006,7 @@ public class XmrWalletService extends XmrWalletBase {
if (wallet != null && !isShutDownStarted) { if (wallet != null && !isShutDownStarted) {
try { try {
cacheWalletInfo(); cacheWalletInfo();
requestSaveMainWallet(); saveWalletWithDelay();
} catch (Exception e) { } catch (Exception e) {
log.warn("Error caching wallet info: " + e.getMessage() + "\n", e); log.warn("Error caching wallet info: " + e.getMessage() + "\n", e);
} }