Skip to content

Commit

Permalink
refactor(cache): Utils to calculate soft and hard TTL (#33844)
Browse files Browse the repository at this point in the history
  • Loading branch information
zharinov authored Jan 28, 2025
1 parent 0f06866 commit 53fa8cc
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 33 deletions.
2 changes: 1 addition & 1 deletion lib/config/presets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { logger } from '../../logger';
import { ExternalHostError } from '../../types/errors/external-host-error';
import * as memCache from '../../util/cache/memory';
import * as packageCache from '../../util/cache/package';
import { getTtlOverride } from '../../util/cache/package/decorator';
import { getTtlOverride } from '../../util/cache/package/ttl';
import { clone } from '../../util/clone';
import { regEx } from '../../util/regex';
import * as template from '../../util/template';
Expand Down
27 changes: 8 additions & 19 deletions lib/util/cache/package/decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { logger } from '../../../logger';
import type { Decorator } from '../../decorator';
import { decorate } from '../../decorator';
import { acquireLock } from '../../mutex';
import { resolveTtlValues } from './ttl';
import type { DecoratorCachedRecord, PackageCacheNamespace } from './types';
import * as packageCache from '.';

Expand Down Expand Up @@ -91,17 +92,13 @@ export function cache<T>({
finalKey,
);

const ttlOverride = getTtlOverride(finalNamespace);
const softTtl = ttlOverride ?? ttlMinutes;

const cacheHardTtlMinutes = GlobalConfig.get(
'cacheHardTtlMinutes',
7 * 24 * 60,
);
let hardTtl = softTtl;
if (methodName === 'getReleases' || methodName === 'getDigest') {
hardTtl = Math.max(softTtl, cacheHardTtlMinutes);
}
const ttlValues = resolveTtlValues(finalNamespace, ttlMinutes);
const softTtl = ttlValues.softTtlMinutes;
const hardTtl =
methodName === 'getReleases' || methodName === 'getDigest'
? ttlValues.hardTtlMinutes
: // Skip two-tier TTL for any intermediate data fetching
softTtl;

let oldData: unknown;
if (oldRecord) {
Expand Down Expand Up @@ -148,11 +145,3 @@ export function cache<T>({
}
});
}

export function getTtlOverride(namespace: string): number | undefined {
const ttl: unknown = GlobalConfig.get('cacheTtlOverride', {})[namespace];
if (is.number(ttl)) {
return ttl;
}
return undefined;
}
43 changes: 43 additions & 0 deletions lib/util/cache/package/ttl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import is from '@sindresorhus/is';
import { GlobalConfig } from '../../../config/global';
import type { PackageCacheNamespace } from './types';

export function getTtlOverride(
namespace: PackageCacheNamespace,
): number | undefined {
const ttl = GlobalConfig.get('cacheTtlOverride', {})[namespace];
if (is.number(ttl)) {
return ttl;
}
return undefined;
}

export interface TTLValues {
/** TTL for serving cached value without hitting the server */
softTtlMinutes: number;

/** TTL for serving stale cache when upstream responds with errors */
hardTtlMinutes: number;
}

/**
* Apply user-configured overrides and return the final values for soft/hard TTL.
*
* @param namespace Cache namespace
* @param ttlMinutes TTL value configured in Renovate codebase
* @returns
*/
export function resolveTtlValues(
namespace: PackageCacheNamespace,
ttlMinutes: number,
): TTLValues {
const softTtlMinutes = getTtlOverride(namespace) ?? ttlMinutes;

const cacheHardTtlMinutes = GlobalConfig.get(
'cacheHardTtlMinutes',
7 * 24 * 60,
);
const hardTtlMinutes = Math.max(softTtlMinutes, cacheHardTtlMinutes);

return { softTtlMinutes, hardTtlMinutes };
}
2 changes: 1 addition & 1 deletion lib/util/http/cache/package-http-cache-provider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('util/http/cache/package-http-cache-provider', () => {
};
const cacheProvider = new PackageHttpCacheProvider({
namespace: '_test-namespace',
softTtlMinutes: 0,
ttlMinutes: 0,
});
httpMock.scope(url).get('').reply(200, 'new response');

Expand Down
28 changes: 16 additions & 12 deletions lib/util/http/cache/package-http-cache-provider.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
import { DateTime } from 'luxon';
import { get, set } from '../../cache/package'; // Import the package cache functions
import { resolveTtlValues } from '../../cache/package/ttl';
import type { PackageCacheNamespace } from '../../cache/package/types';
import { HttpCacheStats } from '../../stats';
import type { HttpResponse } from '../types';
import { AbstractHttpCacheProvider } from './abstract-http-cache-provider';
import type { HttpCache } from './schema';

export interface PackageHttpCacheProviderOptions {
namespace: PackageCacheNamespace;
softTtlMinutes?: number;
hardTtlMinutes?: number;
ttlMinutes?: number;
}

export class PackageHttpCacheProvider extends AbstractHttpCacheProvider {
private namespace: PackageCacheNamespace;
private softTtlMinutes = 15;
private hardTtlMinutes = 24 * 60;

constructor({
namespace,
softTtlMinutes,
hardTtlMinutes,
}: PackageHttpCacheProviderOptions) {

private softTtlMinutes: number;
private hardTtlMinutes: number;

constructor({ namespace, ttlMinutes = 15 }: PackageHttpCacheProviderOptions) {
super();
this.namespace = namespace;
this.softTtlMinutes = softTtlMinutes ?? this.softTtlMinutes;
this.hardTtlMinutes = hardTtlMinutes ?? this.hardTtlMinutes;
const { softTtlMinutes, hardTtlMinutes } = resolveTtlValues(
this.namespace,
ttlMinutes,
);
this.softTtlMinutes = softTtlMinutes;
this.hardTtlMinutes = hardTtlMinutes;
}

async load(url: string): Promise<unknown> {
Expand All @@ -47,9 +49,11 @@ export class PackageHttpCacheProvider extends AbstractHttpCacheProvider {
const deadline = cachedAt.plus({ minutes: this.softTtlMinutes });
const now = DateTime.now();
if (now >= deadline) {
HttpCacheStats.incLocalMisses(url);
return null;
}

HttpCacheStats.incLocalHits(url);
return cached.httpResponse as HttpResponse<T>;
}
}

0 comments on commit 53fa8cc

Please sign in to comment.