@saltcute/cache 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cache.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare class Cache<T extends object> {
1
+ export declare class Cache<T extends object | Buffer> {
2
2
  private namespace;
3
3
  private static readonly REDIS_HOT_KEY_MEM_CACHE_TTL;
4
4
  private logger;
package/dist/cache.js CHANGED
@@ -15,13 +15,28 @@ class Cache {
15
15
  this.namespace = namespace;
16
16
  this.logger = logger_1.logger.child().withPrefix(`[${this.namespace}:cache]`);
17
17
  this.memCache = new memory_cache_1.Cache();
18
- this.redisClient = (0, redis_1.createClient)();
19
- this.redisClient.on("error", async () => {
20
- this.logger.error("Redis connection error, using memory-cache.");
18
+ this.redisClient = (0, redis_1.createClient)({
19
+ socket: {
20
+ reconnectStrategy: (retries) => Math.min(retries * 100, 3000),
21
+ },
22
+ });
23
+ this.redisClient.on("error", async (e) => {
24
+ if (this.isRedisAvailable) {
25
+ this.logger
26
+ .withError(e)
27
+ .error("Redis connection error, using memory-cache.");
28
+ this.isRedisAvailable = false;
29
+ }
30
+ });
31
+ this.redisClient.connect().catch((e) => {
32
+ this.logger
33
+ .withError(e)
34
+ .error("Redis connection error, using memory-cache.");
21
35
  this.isRedisAvailable = false;
22
- this.redisClient.destroy();
23
36
  });
24
- this.redisClient.connect();
37
+ this.redisClient.on("ready", () => {
38
+ this.isRedisAvailable = true; // recover when the socket comes back
39
+ });
25
40
  }
26
41
  getKey(key) {
27
42
  return `${this.namespace}:${key}`;
@@ -34,26 +49,33 @@ class Cache {
34
49
  */
35
50
  async get(key) {
36
51
  const memCacheValue = this.memCache.get(this.getKey(key));
37
- if (!memCacheValue && this.isRedisAvailable) {
38
- const redisReadBegin = performance.now();
39
- const redisValue = await this.redisClient.get(this.getKey(key));
40
- const redisReadLapsed = performance.now() - redisReadBegin;
41
- if (redisValue) {
42
- try {
43
- const parsed = JSON.parse(redisValue);
44
- this.memCache.put(this.getKey(key), parsed, Cache.REDIS_HOT_KEY_MEM_CACHE_TTL);
45
- this.logger.trace(`GET "${this.getKey(key)}" Redis HIT, took ${redisReadLapsed.toFixed(1)}ms.`);
46
- return parsed;
47
- }
48
- catch {
49
- this.logger.trace(`GET "${this.getKey(key)}" Redis INVALID, took ${redisReadLapsed.toFixed(1)}ms.`);
50
- await this.redisClient.del(this.getKey(key));
51
- return null;
52
+ try {
53
+ if (!memCacheValue && this.isRedisAvailable) {
54
+ const redisReadBegin = performance.now();
55
+ const redisValue = await this.redisClient.get(this.getKey(key));
56
+ const redisReadLapsed = performance.now() - redisReadBegin;
57
+ if (redisValue) {
58
+ try {
59
+ const parsed = JSON.parse(redisValue);
60
+ this.memCache.put(this.getKey(key), parsed, Cache.REDIS_HOT_KEY_MEM_CACHE_TTL);
61
+ this.logger.trace(`GET "${this.getKey(key)}" Redis HIT, took ${redisReadLapsed.toFixed(1)}ms.`);
62
+ return parsed;
63
+ }
64
+ catch {
65
+ const parsed = Buffer.from(redisValue, "base64");
66
+ return parsed;
67
+ }
52
68
  }
53
69
  }
70
+ else {
71
+ return memCacheValue;
72
+ }
54
73
  }
55
- else {
56
- return memCacheValue;
74
+ catch (e) {
75
+ this.logger
76
+ .withError(e)
77
+ .warn(`Redis GET failed for "${this.getKey(key)}", falling back to memory-cache.`);
78
+ return this.memCache.get(this.getKey(key));
57
79
  }
58
80
  }
59
81
  /**
@@ -67,12 +89,29 @@ class Cache {
67
89
  const putBegin = performance.now();
68
90
  if (this.isRedisAvailable) {
69
91
  this.memCache.put(this.getKey(key), value, Cache.REDIS_HOT_KEY_MEM_CACHE_TTL);
70
- await this.redisClient.set(this.getKey(key), JSON.stringify(value), {
71
- expiration: {
72
- type: "EX",
73
- value: Math.trunc(ttl / 1000),
74
- },
75
- });
92
+ try {
93
+ if (value instanceof Buffer) {
94
+ await this.redisClient.set(this.getKey(key), value.toString("base64"), {
95
+ expiration: {
96
+ type: "EX",
97
+ value: Math.trunc(ttl / 1000),
98
+ },
99
+ });
100
+ }
101
+ else {
102
+ await this.redisClient.set(this.getKey(key), JSON.stringify(value), {
103
+ expiration: {
104
+ type: "EX",
105
+ value: Math.trunc(ttl / 1000),
106
+ },
107
+ });
108
+ }
109
+ }
110
+ catch (e) {
111
+ this.logger
112
+ .withError(e)
113
+ .warn(`Redis PUT failed for "${this.getKey(key)}", value kept in memory-cache only.`);
114
+ }
76
115
  }
77
116
  else
78
117
  this.memCache.put(this.getKey(key), value, ttl);
package/dist/cache.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saltcute/cache",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Layered cache.",
5
5
  "homepage": "https://github.com/saltcute/cache#readme",
6
6
  "bugs": {