retry operations from db / after failure

This commit is contained in:
Florian Dold 2016-05-24 01:18:23 +02:00
parent cb7e04c041
commit 50fb0f2beb
2 changed files with 55 additions and 5 deletions

View File

@ -119,6 +119,9 @@ export interface ReserveCreationInfo {
} }
/**
* A coin that isn't yet signed by an exchange.
*/
export interface PreCoin { export interface PreCoin {
coinPub: string; coinPub: string;
coinPriv: string; coinPriv: string;

View File

@ -261,6 +261,11 @@ function getTalerStampSec(stamp: string) {
} }
function setTimeout(f, t) {
return chrome.extension.getBackgroundPage().setTimeout(f, t);
}
function isWithdrawableDenom(d: Denomination) { function isWithdrawableDenom(d: Denomination) {
const now_sec = (new Date).getTime() / 1000; const now_sec = (new Date).getTime() / 1000;
const stamp_withdraw_sec = getTalerStampSec(d.stamp_expire_withdraw); const stamp_withdraw_sec = getTalerStampSec(d.stamp_expire_withdraw);
@ -343,6 +348,31 @@ export class Wallet {
this.badge = badge; this.badge = badge;
this.notifier = notifier; this.notifier = notifier;
this.cryptoApi = new CryptoApi(); this.cryptoApi = new CryptoApi();
this.resumePendingFromDb();
}
/**
* Resume various pending operations that are pending
* by looking at the database.
*/
private resumePendingFromDb(): void {
console.log("resuming pending operations from db");
Query(this.db)
.iter("reserves")
.reduce((reserve: any) => {
console.log("resuming reserve", reserve.reserve_pub);
this.processReserve(reserve);
});
Query(this.db)
.iter("precoins")
.reduce((preCoin: any) => {
console.log("resuming precoin");
this.processPreCoin(preCoin);
});
} }
@ -578,7 +608,8 @@ export class Wallet {
* First fetch information requred to withdraw from the reserve, * First fetch information requred to withdraw from the reserve,
* then deplete the reserve, withdrawing coins until it is empty. * then deplete the reserve, withdrawing coins until it is empty.
*/ */
private processReserve(reserveRecord) { private processReserve(reserveRecord): void {
let retryDelayMs = 100;
this.updateExchangeFromUrl(reserveRecord.exchange_base_url) this.updateExchangeFromUrl(reserveRecord.exchange_base_url)
.then((exchange) => .then((exchange) =>
this.updateReserve(reserveRecord.reserve_pub, exchange) this.updateReserve(reserveRecord.reserve_pub, exchange)
@ -597,6 +628,23 @@ export class Wallet {
.catch((e) => { .catch((e) => {
console.error("Failed to deplete reserve"); console.error("Failed to deplete reserve");
console.error(e); console.error(e);
setTimeout(() => this.processReserve(reserveRecord), retryDelayMs);
// exponential backoff truncated at one minute
retryDelayMs = Math.min(retryDelayMs * 2, 1000 * 60);
});
}
private processPreCoin(preCoin): void {
let retryDelayMs = 100;
this.withdrawExecute(preCoin)
.then((c) => this.storeCoin(c))
.catch((e) => {
console.error("Failed to withdraw coin from precoin");
console.error(e);
setTimeout(() => this.processPreCoin(preCoin), retryDelayMs);
// exponential backoff truncated at one minute
retryDelayMs = Math.min(retryDelayMs * 2, 1000 * 60);
}); });
} }
@ -735,7 +783,7 @@ export class Wallet {
/** /**
* Withdraw one coins of the given denomination from the given reserve. * Withdraw one coin of the given denomination from the given reserve.
*/ */
private withdraw(denom: Denomination, reserve: Reserve): Promise<void> { private withdraw(denom: Denomination, reserve: Reserve): Promise<void> {
console.log("creating pre coin at", new Date()); console.log("creating pre coin at", new Date());
@ -745,8 +793,7 @@ export class Wallet {
return Query(this.db) return Query(this.db)
.put("precoins", preCoin) .put("precoins", preCoin)
.finish() .finish()
.then(() => this.withdrawExecute(preCoin)) .then(() => this.processPreCoin(preCoin));
.then((c) => this.storeCoin(c));
}); });
} }