(
client: CachingClient,
parser: BasicCommandParser,
fn: CmdFunc,
transformReply?: TransformReply,
typeMapping?: TypeMapping
)
| 541 | 4. return previously non cached result |
| 542 | */ |
| 543 | override async handleCache( |
| 544 | client: CachingClient, |
| 545 | parser: BasicCommandParser, |
| 546 | fn: CmdFunc, |
| 547 | transformReply?: TransformReply, |
| 548 | typeMapping?: TypeMapping |
| 549 | ) { |
| 550 | let reply: ReplyUnion; |
| 551 | |
| 552 | const cacheKey = generateCacheKey(parser.redisArgs); |
| 553 | |
| 554 | // "2" |
| 555 | let cacheEntry = this.get(cacheKey); |
| 556 | |
| 557 | if (cacheEntry) { |
| 558 | // If instanceof is "too slow", can add a "type" and then use an "as" cast to call proper getters. |
| 559 | if (cacheEntry instanceof ClientSideCacheEntryValue) { // "2b1" |
| 560 | this.#statsCounter.recordHits(1); |
| 561 | publish(CHANNELS.CACHE_REQUEST, () => ({ result: 'hit', clientId: client._clientId })); |
| 562 | |
| 563 | return structuredClone(cacheEntry.value); |
| 564 | } else if (cacheEntry instanceof ClientSideCacheEntryPromise) { // 2b2 |
| 565 | // This counts as a miss since the value hasn't been fully loaded yet. |
| 566 | this.#statsCounter.recordMisses(1); |
| 567 | publish(CHANNELS.CACHE_REQUEST, () => ({ result: 'miss', clientId: client._clientId })); |
| 568 | reply = await cacheEntry.promise; |
| 569 | } else { |
| 570 | throw new Error("unknown cache entry type"); |
| 571 | } |
| 572 | } else { // 3/3a |
| 573 | this.#statsCounter.recordMisses(1); |
| 574 | publish(CHANNELS.CACHE_REQUEST, () => ({ result: 'miss', clientId: client._clientId })); |
| 575 | |
| 576 | const startTime = performance.now(); |
| 577 | const promise = fn(); |
| 578 | |
| 579 | cacheEntry = this.createPromiseEntry(client, promise); |
| 580 | this.set(cacheKey, cacheEntry, parser.keys); |
| 581 | |
| 582 | try { |
| 583 | reply = await promise; |
| 584 | const loadTime = performance.now() - startTime; |
| 585 | this.#statsCounter.recordLoadSuccess(loadTime); |
| 586 | } catch (err) { |
| 587 | const loadTime = performance.now() - startTime; |
| 588 | this.#statsCounter.recordLoadFailure(loadTime); |
| 589 | |
| 590 | if (cacheEntry.validate()) { |
| 591 | this.delete(cacheKey!); |
| 592 | } |
| 593 | |
| 594 | throw err; |
| 595 | } |
| 596 | } |
| 597 | |
| 598 | // 3b |
| 599 | let val; |
| 600 | if (transformReply) { |
no test coverage detected