Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/gitpod-protocol/src/util/garbage-collected-cache.ts
2500 views
1
/**
2
* Copyright (c) 2020 Gitpod GmbH. All rights reserved.
3
* Licensed under the GNU Affero General Public License (AGPL).
4
* See License.AGPL.txt in the project root for license information.
5
*/
6
7
import { repeat } from "./repeat";
8
9
interface CacheEntry<T> {
10
key: string;
11
value: T;
12
expiryDate: number;
13
}
14
15
export class GarbageCollectedCache<T> {
16
protected readonly store = new Map<string, CacheEntry<T>>();
17
18
constructor(protected readonly defaultMaxAgeSeconds: number, protected readonly gcIntervalSeconds: number) {
19
this.regularlyCollectGarbage();
20
}
21
22
public set(key: string, value: T) {
23
const oldValue = this.store.get(key);
24
if (oldValue) {
25
// We don't want values to be cached indefinitely just because their queried often
26
return;
27
}
28
this.store.set(key, {
29
key,
30
value,
31
expiryDate: this.calcExpiryDate(),
32
});
33
}
34
35
public get(key: string): T | undefined {
36
const entry = this.store.get(key);
37
if (!entry) {
38
return undefined;
39
}
40
// Still valid?
41
if (entry.expiryDate < Date.now()) {
42
this.store.delete(entry.key);
43
return undefined;
44
}
45
return entry.value;
46
}
47
48
public delete(key: string) {
49
this.store.delete(key);
50
}
51
52
protected regularlyCollectGarbage() {
53
repeat(() => this.collectGarbage(), this.gcIntervalSeconds * 1000);
54
}
55
56
protected collectGarbage() {
57
const now = Date.now();
58
for (const entry of this.store.values()) {
59
if (entry.expiryDate < now) {
60
this.store.delete(entry.key);
61
}
62
}
63
}
64
65
protected calcExpiryDate(maxAgeSeconds?: number): number {
66
return Date.now() + (maxAgeSeconds || this.defaultMaxAgeSeconds) * 1000;
67
}
68
}
69
70