fix: cache hits on falsy values, method and caller in the key, and failure handling - #2
Open
sur-ser wants to merge 4 commits into
Open
fix: cache hits on falsy values, method and caller in the key, and failure handling#2sur-ser wants to merge 4 commits into
sur-ser wants to merge 4 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Nine defects in
CacheableInterceptorandNestjsCacheableService, each reproduced by a test that fails onmainand passes here. The new tests live incacheable.interceptor.regression.spec.ts.if (cachedValue)treats a hit as a miss for falsy values0,'',falseornullis never served from cache and runs on every requestrequest.url, without the methodPOST /itemsresponse is stored under/itemsand then served toGET /itemsfirstValueFrom(next.handle())JSON.stringify(value)in the log line ofset()TypeError: Converting circular structure to JSON; every response body is also written to the log atlogleveldisconnect()only closessecondaryTwo more, outside the runtime:
peerDependenciesdoes not list@nestjs/commonor@nestjs/core, although the library imports both. Consumers get no compatibility signal and no warning on a mismatched Nest version.@m8a-io/nestjs-cacheable, while the package is published as@m8a/nestjs-cacheable(the install line one screen above uses the right name). Copy-pasting any example fails to resolve.What changed
Interceptor
{ value }envelope, so a cached falsy value is a hit. A miss is nowundefined, not "falsy".METHOD:url, and onlyGETandHEADare cached at all. A mutation response can no longer be served to a read.request.user,Authorization,Cookie) are not cached by default.getCacheKeyandisPerCallerareprotected, so caching them under a per-user key is a three line subclass, shown in the README.shareReplay, and the entry is dropped from the in-flight map on completion.debugand the request is answered from the handler.Service
disconnect()closes the primary store as well as the secondary.set()returns the result of the underlying write instead of a hardcodedtrue.logtodebug.set()andCacheTTLacceptnumber | string, matchingCacheableOptions.ttl, which already allowed both.Behaviour changes to be aware of
{ value }. Anything left in a shared Redis from a previous version reads as a miss and is overwritten. Harmless, but worth a line in the release notes.getCacheKey. This is the fix for defect 3, and it is the conservative direction: the previous behaviour served one user's response to another. If you would rather keep caching them by url, that is a one line change, but I would not recommend shipping it as a default.GETandHEADare cached. Previously any method was.Testing
npm test: 27 tests, all green.mainhas 18.cacheable.interceptor.spec.tswere updated, since they encoded the old contract (raw value, key without method).npx tsc --noEmit -p libs/nestjs-cacheable/tsconfig.lib.jsonand the library build are clean.npm run test:e2ewas not run here:test/globalSetup.tsrequires a Redis reachable onlocalhost:6379and I did not want to write into an unrelated instance. The e2e specs issue plain unauthenticatedGET /testrequests, so the new key and the credential rule do not change what they assert.npm run lintis not clean on this branch, but it is not clean onmaineither (19 errors before, and the--fixpass rewrites the whole repository because the committed sources are formatted without semicolons while.prettierrcleavessemiat its default). I kept the existing style in the files I touched rather than reformat them, so the diff stays readable.