@trieb.work/nextjs-turbo-redis-cache 1.8.0-beta.4 → 1.8.0-beta.6
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/CHANGELOG.md +14 -0
- package/README.md +16 -16
- package/dist/index.d.mts +7 -5
- package/dist/index.d.ts +7 -5
- package/dist/index.js +25 -36
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +25 -36
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/RedisStringsHandler.ts +23 -37
- package/src/SyncedMap.ts +22 -33
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [1.8.0-beta.6](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.8.0-beta.5...v1.8.0-beta.6) (2025-06-13)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* remove general timeoutMs and replace it with getTimeoutMs (for faster non-blocking rendering) ([02deb64](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/02deb649fce40085495c6fec5e8750cba42d2428))
|
|
7
|
+
|
|
8
|
+
# [1.8.0-beta.5](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.8.0-beta.4...v1.8.0-beta.5) (2025-06-12)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* scan+hscan logging ([56c82c3](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/56c82c3dd62257e8686fedc25dea45a0b7fec18e))
|
|
14
|
+
|
|
1
15
|
# [1.8.0-beta.4](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.8.0-beta.3...v1.8.0-beta.4) (2025-06-12)
|
|
2
16
|
|
|
3
17
|
|
package/README.md
CHANGED
|
@@ -123,22 +123,22 @@ A working example of above can be found in the `test/integration/next-app-custom
|
|
|
123
123
|
|
|
124
124
|
## Available Options
|
|
125
125
|
|
|
126
|
-
| Option | Description
|
|
127
|
-
| ----------------------------- |
|
|
128
|
-
| redisUrl | Redis connection url
|
|
129
|
-
| database | Redis database number to use. Uses DB 0 for production, DB 1 otherwise
|
|
130
|
-
| keyPrefix | Prefix added to all Redis keys
|
|
131
|
-
| sharedTagsKey | Key used to store shared tags hash map in Redis
|
|
132
|
-
|
|
|
133
|
-
| revalidateTagQuerySize | Number of entries to query in one batch during full sync of shared tags hash map
|
|
134
|
-
| avgResyncIntervalMs | Average interval in milliseconds between tag map full re-syncs
|
|
135
|
-
| redisGetDeduplication | Enable deduplication of Redis get requests via internal in-memory cache.
|
|
136
|
-
| inMemoryCachingTime | Time in milliseconds to cache Redis get results in memory. Set this to 0 to disable in-memory caching completely.
|
|
137
|
-
| defaultStaleAge | Default stale age in seconds for cached items
|
|
138
|
-
| estimateExpireAge | Function to calculate expire age (redis TTL value) from stale age
|
|
139
|
-
| socketOptions | Redis client socket options for TLS/SSL configuration (e.g., `{ tls: true, rejectUnauthorized: false }`)
|
|
140
|
-
| clientOptions | Additional Redis client options (e.g., username, password)
|
|
141
|
-
| killContainerOnErrorThreshold | Number of consecutive errors before the container is killed. Set to 0 to disable.
|
|
126
|
+
| Option | Description | Default Value |
|
|
127
|
+
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
128
|
+
| redisUrl | Redis connection url | `process.env.REDIS_URL? process.env.REDIS_URL : process.env.REDISHOST ? redis://${process.env.REDISHOST}:${process.env.REDISPORT} : 'redis://localhost:6379'` |
|
|
129
|
+
| database | Redis database number to use. Uses DB 0 for production, DB 1 otherwise | `process.env.VERCEL_ENV === 'production' ? 0 : 1` |
|
|
130
|
+
| keyPrefix | Prefix added to all Redis keys | `process.env.VERCEL_URL \|\| 'UNDEFINED_URL_'` |
|
|
131
|
+
| sharedTagsKey | Key used to store shared tags hash map in Redis | `'__sharedTags__'` |
|
|
132
|
+
| getTimeoutMs | Timeout in milliseconds for time critical Redis operations. If Redis get is not fulfilled within this time, returns null to avoid blocking site rendering. | `process.env.REDIS_COMMAND_TIMEOUT_MS ? (Number.parseInt(process.env.REDIS_COMMAND_TIMEOUT_MS) ?? 500) : 500` |
|
|
133
|
+
| revalidateTagQuerySize | Number of entries to query in one batch during full sync of shared tags hash map | `250` |
|
|
134
|
+
| avgResyncIntervalMs | Average interval in milliseconds between tag map full re-syncs | `3600000` (1 hour) |
|
|
135
|
+
| redisGetDeduplication | Enable deduplication of Redis get requests via internal in-memory cache. | `true` |
|
|
136
|
+
| inMemoryCachingTime | Time in milliseconds to cache Redis get results in memory. Set this to 0 to disable in-memory caching completely. | `10000` |
|
|
137
|
+
| defaultStaleAge | Default stale age in seconds for cached items | `1209600` (14 days) |
|
|
138
|
+
| estimateExpireAge | Function to calculate expire age (redis TTL value) from stale age | Production: `staleAge * 2`<br> Other: `staleAge * 1.2` |
|
|
139
|
+
| socketOptions | Redis client socket options for TLS/SSL configuration (e.g., `{ tls: true, rejectUnauthorized: false }`) | `{ connectTimeout: timeoutMs }` |
|
|
140
|
+
| clientOptions | Additional Redis client options (e.g., username, password) | `undefined` |
|
|
141
|
+
| killContainerOnErrorThreshold | Number of consecutive errors before the container is killed. Set to 0 to disable. | `Number.parseInt(process.env.KILL_CONTAINER_ON_ERROR_THRESHOLD) ?? 0 : 0` |
|
|
142
142
|
|
|
143
143
|
## TLS Configuration
|
|
144
144
|
|
package/dist/index.d.mts
CHANGED
|
@@ -20,10 +20,12 @@ type CreateRedisStringsHandlerOptions = {
|
|
|
20
20
|
* @default process.env.VERCEL_URL || 'UNDEFINED_URL_'
|
|
21
21
|
*/
|
|
22
22
|
keyPrefix?: string;
|
|
23
|
-
/** Timeout in milliseconds for Redis operations
|
|
24
|
-
*
|
|
23
|
+
/** Timeout in milliseconds for time critical Redis operations (during cache get, which blocks site rendering).
|
|
24
|
+
* If redis get is not fulfilled within this time, the cache handler will return null so site rendering will
|
|
25
|
+
* not be blocked further and site can fallback to re-render/re-fetch the content.
|
|
26
|
+
* @default 500
|
|
25
27
|
*/
|
|
26
|
-
|
|
28
|
+
getTimeoutMs?: number;
|
|
27
29
|
/** Number of entries to query in one batch during full sync of shared tags hash map
|
|
28
30
|
* @default 250
|
|
29
31
|
*/
|
|
@@ -70,17 +72,17 @@ declare class RedisStringsHandler {
|
|
|
70
72
|
private sharedTagsMap;
|
|
71
73
|
private revalidatedTagsMap;
|
|
72
74
|
private inMemoryDeduplicationCache;
|
|
75
|
+
private getTimeoutMs;
|
|
73
76
|
private redisGet;
|
|
74
77
|
private redisDeduplicationHandler;
|
|
75
78
|
private deduplicatedRedisGet;
|
|
76
|
-
private timeoutMs;
|
|
77
79
|
private keyPrefix;
|
|
78
80
|
private redisGetDeduplication;
|
|
79
81
|
private inMemoryCachingTime;
|
|
80
82
|
private defaultStaleAge;
|
|
81
83
|
private estimateExpireAge;
|
|
82
84
|
private killContainerOnErrorThreshold;
|
|
83
|
-
constructor({ redisUrl, database, keyPrefix, sharedTagsKey,
|
|
85
|
+
constructor({ redisUrl, database, keyPrefix, sharedTagsKey, getTimeoutMs, revalidateTagQuerySize, avgResyncIntervalMs, redisGetDeduplication, inMemoryCachingTime, defaultStaleAge, estimateExpireAge, killContainerOnErrorThreshold, socketOptions, clientOptions, }: CreateRedisStringsHandlerOptions);
|
|
84
86
|
resetRequestCache(): void;
|
|
85
87
|
private clientReadyCalls;
|
|
86
88
|
private assertClientIsReady;
|
package/dist/index.d.ts
CHANGED
|
@@ -20,10 +20,12 @@ type CreateRedisStringsHandlerOptions = {
|
|
|
20
20
|
* @default process.env.VERCEL_URL || 'UNDEFINED_URL_'
|
|
21
21
|
*/
|
|
22
22
|
keyPrefix?: string;
|
|
23
|
-
/** Timeout in milliseconds for Redis operations
|
|
24
|
-
*
|
|
23
|
+
/** Timeout in milliseconds for time critical Redis operations (during cache get, which blocks site rendering).
|
|
24
|
+
* If redis get is not fulfilled within this time, the cache handler will return null so site rendering will
|
|
25
|
+
* not be blocked further and site can fallback to re-render/re-fetch the content.
|
|
26
|
+
* @default 500
|
|
25
27
|
*/
|
|
26
|
-
|
|
28
|
+
getTimeoutMs?: number;
|
|
27
29
|
/** Number of entries to query in one batch during full sync of shared tags hash map
|
|
28
30
|
* @default 250
|
|
29
31
|
*/
|
|
@@ -70,17 +72,17 @@ declare class RedisStringsHandler {
|
|
|
70
72
|
private sharedTagsMap;
|
|
71
73
|
private revalidatedTagsMap;
|
|
72
74
|
private inMemoryDeduplicationCache;
|
|
75
|
+
private getTimeoutMs;
|
|
73
76
|
private redisGet;
|
|
74
77
|
private redisDeduplicationHandler;
|
|
75
78
|
private deduplicatedRedisGet;
|
|
76
|
-
private timeoutMs;
|
|
77
79
|
private keyPrefix;
|
|
78
80
|
private redisGetDeduplication;
|
|
79
81
|
private inMemoryCachingTime;
|
|
80
82
|
private defaultStaleAge;
|
|
81
83
|
private estimateExpireAge;
|
|
82
84
|
private killContainerOnErrorThreshold;
|
|
83
|
-
constructor({ redisUrl, database, keyPrefix, sharedTagsKey,
|
|
85
|
+
constructor({ redisUrl, database, keyPrefix, sharedTagsKey, getTimeoutMs, revalidateTagQuerySize, avgResyncIntervalMs, redisGetDeduplication, inMemoryCachingTime, defaultStaleAge, estimateExpireAge, killContainerOnErrorThreshold, socketOptions, clientOptions, }: CreateRedisStringsHandlerOptions);
|
|
84
86
|
resetRequestCache(): void;
|
|
85
87
|
private clientReadyCalls;
|
|
86
88
|
private assertClientIsReady;
|
package/dist/index.js
CHANGED
|
@@ -58,7 +58,6 @@ var SyncedMap = class {
|
|
|
58
58
|
this.redisKey = options.redisKey;
|
|
59
59
|
this.syncChannel = `${options.keyPrefix}${SYNC_CHANNEL_SUFFIX}${options.redisKey}`;
|
|
60
60
|
this.database = options.database;
|
|
61
|
-
this.timeoutMs = options.timeoutMs;
|
|
62
61
|
this.querySize = options.querySize;
|
|
63
62
|
this.filterKeys = options.filterKeys;
|
|
64
63
|
this.resyncIntervalMs = options.resyncIntervalMs;
|
|
@@ -88,11 +87,13 @@ var SyncedMap = class {
|
|
|
88
87
|
const hScanOptions = { COUNT: this.querySize };
|
|
89
88
|
try {
|
|
90
89
|
do {
|
|
91
|
-
const remoteItems = await
|
|
92
|
-
|
|
93
|
-
this.
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
const remoteItems = await redisErrorHandler(
|
|
91
|
+
"SyncedMap.initialSync(), operation: hScan " + this.syncChannel + " " + this.keyPrefix + " " + this.redisKey + " " + cursor + " " + this.querySize,
|
|
92
|
+
this.client.hScan(
|
|
93
|
+
this.keyPrefix + this.redisKey,
|
|
94
|
+
cursor,
|
|
95
|
+
hScanOptions
|
|
96
|
+
)
|
|
96
97
|
);
|
|
97
98
|
for (const { field, value } of remoteItems.tuples) {
|
|
98
99
|
if (this.filterKeys(field)) {
|
|
@@ -114,10 +115,9 @@ var SyncedMap = class {
|
|
|
114
115
|
let remoteKeys = [];
|
|
115
116
|
try {
|
|
116
117
|
do {
|
|
117
|
-
const remoteKeysPortion = await
|
|
118
|
-
|
|
119
|
-
cursor,
|
|
120
|
-
scanOptions
|
|
118
|
+
const remoteKeysPortion = await redisErrorHandler(
|
|
119
|
+
"SyncedMap.cleanupKeysNotInRedis(), operation: scan " + this.keyPrefix,
|
|
120
|
+
this.client.scan(cursor, scanOptions)
|
|
121
121
|
);
|
|
122
122
|
remoteKeys = remoteKeys.concat(remoteKeysPortion.keys);
|
|
123
123
|
cursor = remoteKeysPortion.cursor;
|
|
@@ -270,12 +270,10 @@ var SyncedMap = class {
|
|
|
270
270
|
return;
|
|
271
271
|
}
|
|
272
272
|
if (!this.customizedSync?.withoutRedisHashmap) {
|
|
273
|
-
const options = getTimeoutRedisCommandOptions(this.timeoutMs);
|
|
274
273
|
operations.push(
|
|
275
274
|
redisErrorHandler(
|
|
276
|
-
"SyncedMap.set(), operation: hSet " + this.syncChannel + " " + this.
|
|
275
|
+
"SyncedMap.set(), operation: hSet " + this.syncChannel + " " + this.keyPrefix + " " + key,
|
|
277
276
|
this.client.hSet(
|
|
278
|
-
options,
|
|
279
277
|
this.keyPrefix + this.redisKey,
|
|
280
278
|
key,
|
|
281
279
|
JSON.stringify(value)
|
|
@@ -290,7 +288,7 @@ var SyncedMap = class {
|
|
|
290
288
|
};
|
|
291
289
|
operations.push(
|
|
292
290
|
redisErrorHandler(
|
|
293
|
-
"SyncedMap.set(), operation: publish " + this.syncChannel + " " + this.
|
|
291
|
+
"SyncedMap.set(), operation: publish " + this.syncChannel + " " + this.keyPrefix + " " + key,
|
|
294
292
|
this.client.publish(this.syncChannel, JSON.stringify(insertMessage))
|
|
295
293
|
)
|
|
296
294
|
);
|
|
@@ -309,11 +307,10 @@ var SyncedMap = class {
|
|
|
309
307
|
this.map.delete(key);
|
|
310
308
|
}
|
|
311
309
|
if (!this.customizedSync?.withoutRedisHashmap) {
|
|
312
|
-
const options = getTimeoutRedisCommandOptions(this.timeoutMs * 10);
|
|
313
310
|
operations.push(
|
|
314
311
|
redisErrorHandler(
|
|
315
|
-
"SyncedMap.delete(), operation: hDel " + this.syncChannel + " " + this.
|
|
316
|
-
this.client.hDel(
|
|
312
|
+
"SyncedMap.delete(), operation: hDel " + this.syncChannel + " " + this.keyPrefix + " " + this.redisKey + " " + keysArray,
|
|
313
|
+
this.client.hDel(this.keyPrefix + this.redisKey, keysArray)
|
|
317
314
|
)
|
|
318
315
|
);
|
|
319
316
|
}
|
|
@@ -324,7 +321,7 @@ var SyncedMap = class {
|
|
|
324
321
|
};
|
|
325
322
|
operations.push(
|
|
326
323
|
redisErrorHandler(
|
|
327
|
-
"SyncedMap.delete(), operation: publish " + this.syncChannel + " " + this.
|
|
324
|
+
"SyncedMap.delete(), operation: publish " + this.syncChannel + " " + this.keyPrefix + " " + keysArray,
|
|
328
325
|
this.client.publish(
|
|
329
326
|
this.syncChannel,
|
|
330
327
|
JSON.stringify(deletionMessage)
|
|
@@ -479,9 +476,6 @@ setInterval(() => {
|
|
|
479
476
|
}, 1e3);
|
|
480
477
|
var NEXT_CACHE_IMPLICIT_TAG_ID = "_N_T_";
|
|
481
478
|
var REVALIDATED_TAGS_KEY = "__revalidated_tags__";
|
|
482
|
-
function getTimeoutRedisCommandOptions(timeoutMs) {
|
|
483
|
-
return (0, import_redis.commandOptions)({ signal: AbortSignal.timeout(timeoutMs) });
|
|
484
|
-
}
|
|
485
479
|
var killContainerOnErrorCount = 0;
|
|
486
480
|
var RedisStringsHandler = class {
|
|
487
481
|
constructor({
|
|
@@ -489,7 +483,7 @@ var RedisStringsHandler = class {
|
|
|
489
483
|
database = process.env.VERCEL_ENV === "production" ? 0 : 1,
|
|
490
484
|
keyPrefix = process.env.VERCEL_URL || "UNDEFINED_URL_",
|
|
491
485
|
sharedTagsKey = "__sharedTags__",
|
|
492
|
-
|
|
486
|
+
getTimeoutMs = process.env.REDIS_COMMAND_TIMEOUT_MS ? Number.parseInt(process.env.REDIS_COMMAND_TIMEOUT_MS) ?? 500 : 500,
|
|
493
487
|
revalidateTagQuerySize = 250,
|
|
494
488
|
avgResyncIntervalMs = 60 * 60 * 1e3,
|
|
495
489
|
redisGetDeduplication = true,
|
|
@@ -503,12 +497,12 @@ var RedisStringsHandler = class {
|
|
|
503
497
|
this.clientReadyCalls = 0;
|
|
504
498
|
try {
|
|
505
499
|
this.keyPrefix = keyPrefix;
|
|
506
|
-
this.timeoutMs = timeoutMs;
|
|
507
500
|
this.redisGetDeduplication = redisGetDeduplication;
|
|
508
501
|
this.inMemoryCachingTime = inMemoryCachingTime;
|
|
509
502
|
this.defaultStaleAge = defaultStaleAge;
|
|
510
503
|
this.estimateExpireAge = estimateExpireAge;
|
|
511
504
|
this.killContainerOnErrorThreshold = killContainerOnErrorThreshold;
|
|
505
|
+
this.getTimeoutMs = getTimeoutMs;
|
|
512
506
|
try {
|
|
513
507
|
this.client = (0, import_redis.createClient)({
|
|
514
508
|
url: redisUrl,
|
|
@@ -565,7 +559,6 @@ var RedisStringsHandler = class {
|
|
|
565
559
|
keyPrefix,
|
|
566
560
|
redisKey: sharedTagsKey,
|
|
567
561
|
database,
|
|
568
|
-
timeoutMs,
|
|
569
562
|
querySize: revalidateTagQuerySize,
|
|
570
563
|
filterKeys,
|
|
571
564
|
resyncIntervalMs: avgResyncIntervalMs - avgResyncIntervalMs / 10 + Math.random() * (avgResyncIntervalMs / 10)
|
|
@@ -575,7 +568,6 @@ var RedisStringsHandler = class {
|
|
|
575
568
|
keyPrefix,
|
|
576
569
|
redisKey: REVALIDATED_TAGS_KEY,
|
|
577
570
|
database,
|
|
578
|
-
timeoutMs,
|
|
579
571
|
querySize: revalidateTagQuerySize,
|
|
580
572
|
filterKeys,
|
|
581
573
|
resyncIntervalMs: avgResyncIntervalMs + avgResyncIntervalMs / 10 + Math.random() * (avgResyncIntervalMs / 10)
|
|
@@ -585,7 +577,6 @@ var RedisStringsHandler = class {
|
|
|
585
577
|
keyPrefix,
|
|
586
578
|
redisKey: "inMemoryDeduplicationCache",
|
|
587
579
|
database,
|
|
588
|
-
timeoutMs,
|
|
589
580
|
querySize: revalidateTagQuerySize,
|
|
590
581
|
filterKeys,
|
|
591
582
|
customizedSync: {
|
|
@@ -638,7 +629,7 @@ var RedisStringsHandler = class {
|
|
|
638
629
|
"assertClientIsReady: Timeout waiting for Redis maps to be ready"
|
|
639
630
|
)
|
|
640
631
|
);
|
|
641
|
-
},
|
|
632
|
+
}, 3e4)
|
|
642
633
|
)
|
|
643
634
|
]);
|
|
644
635
|
this.clientReadyCalls = 0;
|
|
@@ -663,9 +654,9 @@ var RedisStringsHandler = class {
|
|
|
663
654
|
await this.assertClientIsReady();
|
|
664
655
|
const clientGet = this.redisGetDeduplication ? this.deduplicatedRedisGet(key) : this.redisGet;
|
|
665
656
|
const serializedCacheEntry = await redisErrorHandler(
|
|
666
|
-
"RedisStringsHandler.get(), operation: get" + (this.redisGetDeduplication ? "deduplicated" : "") + this.
|
|
657
|
+
"RedisStringsHandler.get(), operation: get" + (this.redisGetDeduplication ? "deduplicated" : "") + " " + this.getTimeoutMs + "ms " + this.keyPrefix + " " + key,
|
|
667
658
|
clientGet(
|
|
668
|
-
|
|
659
|
+
(0, import_redis.commandOptions)({ signal: AbortSignal.timeout(this.getTimeoutMs) }),
|
|
669
660
|
this.keyPrefix + key
|
|
670
661
|
)
|
|
671
662
|
);
|
|
@@ -725,7 +716,7 @@ var RedisStringsHandler = class {
|
|
|
725
716
|
const revalidationTime = this.revalidatedTagsMap.get(tag);
|
|
726
717
|
if (revalidationTime && revalidationTime > cacheEntry.lastModified) {
|
|
727
718
|
const redisKey = this.keyPrefix + key;
|
|
728
|
-
this.client.unlink(
|
|
719
|
+
this.client.unlink(redisKey).catch((err) => {
|
|
729
720
|
console.error(
|
|
730
721
|
"Error occurred while unlinking stale data. Error was:",
|
|
731
722
|
err
|
|
@@ -802,10 +793,9 @@ var RedisStringsHandler = class {
|
|
|
802
793
|
data.kind === "FETCH" && data.revalidate || ctx.revalidate || ctx.cacheControl?.revalidate || data?.revalidate
|
|
803
794
|
);
|
|
804
795
|
const expireAt = revalidate && Number.isSafeInteger(revalidate) && revalidate > 0 ? this.estimateExpireAge(revalidate) : this.estimateExpireAge(this.defaultStaleAge);
|
|
805
|
-
const options = getTimeoutRedisCommandOptions(this.timeoutMs);
|
|
806
796
|
const setOperation = redisErrorHandler(
|
|
807
|
-
"RedisStringsHandler.set(), operation: set
|
|
808
|
-
this.client.set(
|
|
797
|
+
"RedisStringsHandler.set(), operation: set " + this.keyPrefix + " " + key,
|
|
798
|
+
this.client.set(this.keyPrefix + key, serializedCacheEntry, {
|
|
809
799
|
EX: expireAt
|
|
810
800
|
})
|
|
811
801
|
);
|
|
@@ -899,10 +889,9 @@ var RedisStringsHandler = class {
|
|
|
899
889
|
}
|
|
900
890
|
const redisKeys = Array.from(keysToDelete);
|
|
901
891
|
const fullRedisKeys = redisKeys.map((key) => this.keyPrefix + key);
|
|
902
|
-
const options = getTimeoutRedisCommandOptions(this.timeoutMs);
|
|
903
892
|
const deleteKeysOperation = redisErrorHandler(
|
|
904
|
-
"RedisStringsHandler.revalidateTag(), operation: unlink
|
|
905
|
-
this.client.unlink(
|
|
893
|
+
"RedisStringsHandler.revalidateTag(), operation: unlink " + this.keyPrefix + " " + fullRedisKeys,
|
|
894
|
+
this.client.unlink(fullRedisKeys)
|
|
906
895
|
);
|
|
907
896
|
if (this.redisGetDeduplication && this.inMemoryCachingTime > 0) {
|
|
908
897
|
for (const key of keysToDelete) {
|