mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix(feishu): bound probe cache expiry clocks
This commit is contained in:
@@ -187,6 +187,32 @@ describe("probeFeishu", () => {
|
||||
expect(requestFn).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("does not cache probe results when the expiry would exceed a valid Date", async () => {
|
||||
await withFakeTimers(async () => {
|
||||
vi.setSystemTime(new Date(8_640_000_000_000_000));
|
||||
const requestFn = setupSuccessClient();
|
||||
|
||||
const { first, second } = await readSequentialDefaultProbePair();
|
||||
|
||||
expect(first).toEqual(second);
|
||||
expect(requestFn).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
|
||||
it("evicts cached probe results when the current clock is invalid", async () => {
|
||||
const requestFn = setupSuccessClient();
|
||||
|
||||
await probeFeishu(DEFAULT_CREDS);
|
||||
const dateNow = vi.spyOn(Date, "now").mockReturnValue(Number.NaN);
|
||||
try {
|
||||
await probeFeishu(DEFAULT_CREDS);
|
||||
} finally {
|
||||
dateNow.mockRestore();
|
||||
}
|
||||
|
||||
expect(requestFn).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it("makes a fresh API call after cache expires", async () => {
|
||||
await withFakeTimers(async () => {
|
||||
const requestFn = setupSuccessClient();
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
||||
import {
|
||||
asDateTimestampMs,
|
||||
resolveExpiresAtMsFromDurationMs,
|
||||
} from "openclaw/plugin-sdk/number-runtime";
|
||||
import { raceWithTimeoutAndAbort } from "./async.js";
|
||||
import { createFeishuClient, type FeishuClientCredentials } from "./client.js";
|
||||
import type { FeishuProbeResult } from "./types.js";
|
||||
@@ -38,7 +42,12 @@ function setCachedProbeResult(
|
||||
result: FeishuProbeResult,
|
||||
ttlMs: number,
|
||||
): FeishuProbeResult {
|
||||
probeCache.set(cacheKey, { result, expiresAt: Date.now() + ttlMs });
|
||||
const expiresAt = resolveExpiresAtMsFromDurationMs(ttlMs);
|
||||
if (expiresAt === undefined) {
|
||||
probeCache.delete(cacheKey);
|
||||
return result;
|
||||
}
|
||||
probeCache.set(cacheKey, { result, expiresAt });
|
||||
if (probeCache.size > MAX_PROBE_CACHE_SIZE) {
|
||||
const oldest = probeCache.keys().next().value;
|
||||
if (oldest !== undefined) {
|
||||
@@ -74,8 +83,13 @@ export async function probeFeishu(
|
||||
// pollute each other's cache entry.
|
||||
const cacheKey = creds.accountId ?? `${creds.appId}:${creds.appSecret.slice(0, 8)}`;
|
||||
const cached = probeCache.get(cacheKey);
|
||||
if (cached && cached.expiresAt > Date.now()) {
|
||||
return cached.result;
|
||||
if (cached) {
|
||||
const now = asDateTimestampMs(Date.now());
|
||||
const expiresAt = asDateTimestampMs(cached.expiresAt);
|
||||
if (now !== undefined && expiresAt !== undefined && expiresAt > now) {
|
||||
return cached.result;
|
||||
}
|
||||
probeCache.delete(cacheKey);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user