respect cache header
This commit is contained in:
parent
0ffea74ad5
commit
659e9cdbe6
@ -43,16 +43,19 @@ import {
|
|||||||
WALLET_CACHE_BREAKER_CLIENT_VERSION,
|
WALLET_CACHE_BREAKER_CLIENT_VERSION,
|
||||||
WALLET_EXCHANGE_PROTOCOL_VERSION,
|
WALLET_EXCHANGE_PROTOCOL_VERSION,
|
||||||
} from "./versions";
|
} from "./versions";
|
||||||
import { getTimestampNow, Duration } from "../util/time";
|
import { getTimestampNow, Duration, isTimestampExpired } from "../util/time";
|
||||||
import { compare } from "../util/libtoolVersion";
|
import { compare } from "../util/libtoolVersion";
|
||||||
import { createRecoupGroup, processRecoupGroup } from "./recoup";
|
import { createRecoupGroup, processRecoupGroup } from "./recoup";
|
||||||
import { TalerErrorCode } from "../TalerErrorCode";
|
import { TalerErrorCode } from "../TalerErrorCode";
|
||||||
import {
|
import {
|
||||||
readSuccessResponseJsonOrThrow,
|
readSuccessResponseJsonOrThrow,
|
||||||
readSuccessResponseTextOrThrow,
|
readSuccessResponseTextOrThrow,
|
||||||
|
getExpiryTimestamp,
|
||||||
} from "../util/http";
|
} from "../util/http";
|
||||||
import { Logger } from "../util/logging";
|
import { Logger } from "../util/logging";
|
||||||
import { URL } from "../util/url";
|
import { URL } from "../util/url";
|
||||||
|
import { reconcileReserveHistory } from "../util/reserveHistoryUtil";
|
||||||
|
import { checkDbInvariant } from "../util/invariants";
|
||||||
|
|
||||||
const logger = new Logger("exchanges.ts");
|
const logger = new Logger("exchanges.ts");
|
||||||
|
|
||||||
@ -195,6 +198,7 @@ async function updateExchangeWithKeys(
|
|||||||
masterPublicKey: exchangeKeysJson.master_public_key,
|
masterPublicKey: exchangeKeysJson.master_public_key,
|
||||||
protocolVersion: protocolVersion,
|
protocolVersion: protocolVersion,
|
||||||
signingKeys: exchangeKeysJson.signkeys,
|
signingKeys: exchangeKeysJson.signkeys,
|
||||||
|
nextUpdateTime: getExpiryTimestamp(resp),
|
||||||
};
|
};
|
||||||
r.updateStatus = ExchangeUpdateStatus.FetchWire;
|
r.updateStatus = ExchangeUpdateStatus.FetchWire;
|
||||||
r.lastError = undefined;
|
r.lastError = undefined;
|
||||||
@ -459,7 +463,7 @@ async function updateExchangeFromUrlImpl(
|
|||||||
const now = getTimestampNow();
|
const now = getTimestampNow();
|
||||||
baseUrl = canonicalizeBaseUrl(baseUrl);
|
baseUrl = canonicalizeBaseUrl(baseUrl);
|
||||||
|
|
||||||
const r = await ws.db.get(Stores.exchanges, baseUrl);
|
let r = await ws.db.get(Stores.exchanges, baseUrl);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
const newExchangeRecord: ExchangeRecord = {
|
const newExchangeRecord: ExchangeRecord = {
|
||||||
builtIn: false,
|
builtIn: false,
|
||||||
@ -476,7 +480,6 @@ async function updateExchangeFromUrlImpl(
|
|||||||
termsOfServiceAcceptedTimestamp: undefined,
|
termsOfServiceAcceptedTimestamp: undefined,
|
||||||
termsOfServiceLastEtag: undefined,
|
termsOfServiceLastEtag: undefined,
|
||||||
termsOfServiceText: undefined,
|
termsOfServiceText: undefined,
|
||||||
updateDiff: undefined,
|
|
||||||
};
|
};
|
||||||
await ws.db.put(Stores.exchanges, newExchangeRecord);
|
await ws.db.put(Stores.exchanges, newExchangeRecord);
|
||||||
} else {
|
} else {
|
||||||
@ -498,6 +501,16 @@ async function updateExchangeFromUrlImpl(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r = await ws.db.get(Stores.exchanges, baseUrl);
|
||||||
|
checkDbInvariant(!!r);
|
||||||
|
|
||||||
|
|
||||||
|
const t = r.details?.nextUpdateTime;
|
||||||
|
if (!forceNow && t && !isTimestampExpired(t)) {
|
||||||
|
logger.trace("using cached exchange info");
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
await updateExchangeWithKeys(ws, baseUrl);
|
await updateExchangeWithKeys(ws, baseUrl);
|
||||||
await updateExchangeWithWireInfo(ws, baseUrl);
|
await updateExchangeWithWireInfo(ws, baseUrl);
|
||||||
await updateExchangeWithTermsOfService(ws, baseUrl);
|
await updateExchangeWithTermsOfService(ws, baseUrl);
|
||||||
|
@ -539,6 +539,11 @@ export interface ExchangeDetails {
|
|||||||
* Timestamp for last update.
|
* Timestamp for last update.
|
||||||
*/
|
*/
|
||||||
lastUpdateTime: Timestamp;
|
lastUpdateTime: Timestamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When should we next update the information about the exchange?
|
||||||
|
*/
|
||||||
|
nextUpdateTime: Timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ExchangeUpdateStatus {
|
export enum ExchangeUpdateStatus {
|
||||||
|
@ -26,7 +26,7 @@ import { Codec } from "./codec";
|
|||||||
import { OperationFailedError, makeErrorDetails } from "../operations/errors";
|
import { OperationFailedError, makeErrorDetails } from "../operations/errors";
|
||||||
import { TalerErrorCode } from "../TalerErrorCode";
|
import { TalerErrorCode } from "../TalerErrorCode";
|
||||||
import { Logger } from "./logging";
|
import { Logger } from "./logging";
|
||||||
import { Duration } from "./time";
|
import { Duration, Timestamp, getTimestampNow } from "./time";
|
||||||
|
|
||||||
const logger = new Logger("http.ts");
|
const logger = new Logger("http.ts");
|
||||||
|
|
||||||
@ -253,3 +253,19 @@ export async function readSuccessResponseTextOrThrow<T>(
|
|||||||
}
|
}
|
||||||
throwUnexpectedRequestError(httpResponse, r.talerErrorResponse);
|
throwUnexpectedRequestError(httpResponse, r.talerErrorResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the timestamp at which the response's content is considered expired.
|
||||||
|
*/
|
||||||
|
export function getExpiryTimestamp(httpResponse: HttpResponse): Timestamp {
|
||||||
|
const expiryDateMs = new Date(
|
||||||
|
httpResponse.headers.get("expiry") ?? "",
|
||||||
|
).getTime();
|
||||||
|
if (Number.isNaN(expiryDateMs)) {
|
||||||
|
return getTimestampNow();
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
t_ms: expiryDateMs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -46,6 +46,10 @@ export function getTimestampNow(): Timestamp {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isTimestampExpired(t: Timestamp) {
|
||||||
|
return timestampCmp(t, getTimestampNow()) <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
export function getDurationRemaining(
|
export function getDurationRemaining(
|
||||||
deadline: Timestamp,
|
deadline: Timestamp,
|
||||||
now = getTimestampNow(),
|
now = getTimestampNow(),
|
||||||
|
Loading…
Reference in New Issue
Block a user