simplify retry timeout handling

This commit is contained in:
Florian Dold 2021-06-11 11:15:08 +02:00
parent 8ad36d89f5
commit e77510106f
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
12 changed files with 18 additions and 23 deletions

View File

@ -922,7 +922,7 @@ export interface ProposalRecord {
* Retry info, even present when the operation isn't active to allow indexing * Retry info, even present when the operation isn't active to allow indexing
* on the next retry timestamp. * on the next retry timestamp.
*/ */
retryInfo: RetryInfo; retryInfo?: RetryInfo;
lastError: TalerErrorDetails | undefined; lastError: TalerErrorDetails | undefined;
} }

View File

@ -123,7 +123,7 @@ async function resetDepositGroupRetry(
})) }))
.runReadWrite(async (tx) => { .runReadWrite(async (tx) => {
const x = await tx.depositGroups.get(depositGroupId); const x = await tx.depositGroups.get(depositGroupId);
if (x && x.retryInfo.active) { if (x) {
x.retryInfo = initRetryInfo(); x.retryInfo = initRetryInfo();
await tx.depositGroups.put(x); await tx.depositGroups.put(x);
} }

View File

@ -555,7 +555,7 @@ async function resetDownloadProposalRetry(
.mktx((x) => ({ proposals: x.proposals })) .mktx((x) => ({ proposals: x.proposals }))
.runReadWrite(async (tx) => { .runReadWrite(async (tx) => {
const p = await tx.proposals.get(proposalId); const p = await tx.proposals.get(proposalId);
if (p && p.retryInfo.active) { if (p) {
p.retryInfo = initRetryInfo(); p.retryInfo = initRetryInfo();
await tx.proposals.put(p); await tx.proposals.put(p);
} }
@ -574,7 +574,7 @@ async function failProposalPermanently(
if (!p) { if (!p) {
return; return;
} }
p.retryInfo.active = false; delete p.retryInfo;
p.lastError = err; p.lastError = err;
p.proposalStatus = ProposalStatus.PERMANENTLY_FAILED; p.proposalStatus = ProposalStatus.PERMANENTLY_FAILED;
await tx.proposals.put(p); await tx.proposals.put(p);

View File

@ -155,10 +155,11 @@ async function gatherProposalPending(
if (proposal.proposalStatus == ProposalStatus.PROPOSED) { if (proposal.proposalStatus == ProposalStatus.PROPOSED) {
// Nothing to do, user needs to choose. // Nothing to do, user needs to choose.
} else if (proposal.proposalStatus == ProposalStatus.DOWNLOADING) { } else if (proposal.proposalStatus == ProposalStatus.DOWNLOADING) {
const timestampDue = proposal.retryInfo?.nextRetry ?? getTimestampNow();
resp.pendingOperations.push({ resp.pendingOperations.push({
type: PendingOperationType.ProposalDownload, type: PendingOperationType.ProposalDownload,
givesLifeness: true, givesLifeness: true,
timestampDue: proposal.retryInfo.nextRetry, timestampDue,
merchantBaseUrl: proposal.merchantBaseUrl, merchantBaseUrl: proposal.merchantBaseUrl,
orderId: proposal.orderId, orderId: proposal.orderId,
proposalId: proposal.proposalId, proposalId: proposal.proposalId,

View File

@ -316,7 +316,7 @@ async function resetRecoupGroupRetry(
})) }))
.runReadWrite(async (tx) => { .runReadWrite(async (tx) => {
const x = await tx.recoupGroups.get(recoupGroupId); const x = await tx.recoupGroups.get(recoupGroupId);
if (x && x.retryInfo.active) { if (x) {
x.retryInfo = initRetryInfo(); x.retryInfo = initRetryInfo();
await tx.recoupGroups.put(x); await tx.recoupGroups.put(x);
} }

View File

@ -656,7 +656,7 @@ async function resetRefreshGroupRetry(
})) }))
.runReadWrite(async (tx) => { .runReadWrite(async (tx) => {
const x = await tx.refreshGroups.get(refreshGroupId); const x = await tx.refreshGroups.get(refreshGroupId);
if (x && x.retryInfo.active) { if (x) {
x.retryInfo = initRetryInfo(); x.retryInfo = initRetryInfo();
await tx.refreshGroups.put(x); await tx.refreshGroups.put(x);
} }

View File

@ -589,7 +589,7 @@ async function resetPurchaseQueryRefundRetry(
})) }))
.runReadWrite(async (tx) => { .runReadWrite(async (tx) => {
const x = await tx.purchases.get(proposalId); const x = await tx.purchases.get(proposalId);
if (x && x.refundStatusRetryInfo.active) { if (x) {
x.refundStatusRetryInfo = initRetryInfo(); x.refundStatusRetryInfo = initRetryInfo();
await tx.purchases.put(x); await tx.purchases.put(x);
} }

View File

@ -85,7 +85,7 @@ async function resetReserveRetry(
})) }))
.runReadWrite(async (tx) => { .runReadWrite(async (tx) => {
const x = await tx.reserves.get(reservePub); const x = await tx.reserves.get(reservePub);
if (x && x.retryInfo.active) { if (x) {
x.retryInfo = initRetryInfo(); x.retryInfo = initRetryInfo();
await tx.reserves.put(x); await tx.reserves.put(x);
} }

View File

@ -208,7 +208,7 @@ async function resetTipRetry(
})) }))
.runReadWrite(async (tx) => { .runReadWrite(async (tx) => {
const x = await tx.tips.get(tipId); const x = await tx.tips.get(tipId);
if (x && x.retryInfo.active) { if (x) {
x.retryInfo = initRetryInfo(); x.retryInfo = initRetryInfo();
await tx.tips.put(x); await tx.tips.put(x);
} }

View File

@ -790,7 +790,7 @@ async function resetWithdrawalGroupRetry(
.mktx((x) => ({ withdrawalGroups: x.withdrawalGroups })) .mktx((x) => ({ withdrawalGroups: x.withdrawalGroups }))
.runReadWrite(async (tx) => { .runReadWrite(async (tx) => {
const x = await tx.withdrawalGroups.get(withdrawalGroupId); const x = await tx.withdrawalGroups.get(withdrawalGroupId);
if (x && x.retryInfo.active) { if (x) {
x.retryInfo = initRetryInfo(); x.retryInfo = initRetryInfo();
await tx.withdrawalGroups.put(x); await tx.withdrawalGroups.put(x);
} }

View File

@ -132,7 +132,7 @@ export interface PendingProposalDownloadOperation {
proposalId: string; proposalId: string;
orderId: string; orderId: string;
lastError?: TalerErrorDetails; lastError?: TalerErrorDetails;
retryInfo: RetryInfo; retryInfo?: RetryInfo;
} }
/** /**

View File

@ -27,7 +27,6 @@ export interface RetryInfo {
firstTry: Timestamp; firstTry: Timestamp;
nextRetry: Timestamp; nextRetry: Timestamp;
retryCounter: number; retryCounter: number;
active: boolean;
} }
export interface RetryPolicy { export interface RetryPolicy {
@ -52,16 +51,19 @@ export function updateRetryInfoTimeout(
r.nextRetry = { t_ms: "never" }; r.nextRetry = { t_ms: "never" };
return; return;
} }
r.active = true;
const t = const t =
now.t_ms + p.backoffDelta.d_ms * Math.pow(p.backoffBase, r.retryCounter); now.t_ms + p.backoffDelta.d_ms * Math.pow(p.backoffBase, r.retryCounter);
r.nextRetry = { t_ms: t }; r.nextRetry = { t_ms: t };
} }
export function getRetryDuration( export function getRetryDuration(
r: RetryInfo, r: RetryInfo | undefined,
p: RetryPolicy = defaultRetryPolicy, p: RetryPolicy = defaultRetryPolicy,
): Duration { ): Duration {
if (!r) {
// If we don't have any retry info, run immediately.
return { d_ms: 0 };
}
if (p.backoffDelta.d_ms === "forever") { if (p.backoffDelta.d_ms === "forever") {
return { d_ms: "forever" }; return { d_ms: "forever" };
} }
@ -73,14 +75,6 @@ export function initRetryInfo(
active = true, active = true,
p: RetryPolicy = defaultRetryPolicy, p: RetryPolicy = defaultRetryPolicy,
): RetryInfo { ): RetryInfo {
if (!active) {
return {
active: false,
firstTry: { t_ms: Number.MAX_SAFE_INTEGER },
nextRetry: { t_ms: Number.MAX_SAFE_INTEGER },
retryCounter: 0,
};
}
const now = getTimestampNow(); const now = getTimestampNow();
const info = { const info = {
firstTry: now, firstTry: now,