GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||
GeezerVison is showing github.com — feat(cache): add `scope` option to confine invalidation to a tenant by fratzinger · Pull Request #58 · feathersjs/feathers-utils Conversation
Member
Warning WIP — opened for early feedback on the API shape and the safety rules. Not ready to merge. SummaryIn a multi-tenant app every row carries a
cache({ map, transformParams: ({ query }) => ({ query }), scope: (context) => { if (context.method === 'get' || context.method === 'find') { // only scope when the query really pins the tenant down return context.params.query?.companyId } // `update` replaces the row, so the company may change or be dropped if (context.method === 'update') return undefined // a `patch` could move items into another company if (context.method === 'patch' && mayChangeCompany(context.data)) { return undefined } return getResultIsArray(context).result.map((item) => item.companyId) }, }) A Never caching too muchThe guiding rule was: a false hit is unacceptable, a false miss is merely wasteful. So there are three levels, and the middle one is exactly what the hook does without the option:
Enabling Because the common fallback does not call Three bugs fixed along the wayFound while reworking the key parser, each one a stale-data hole:
Each has a regression test, and I verified every one fails against the old implementation. Other InformationTest refactor in the same diff (sorry). The three near-identical storage blocks ( Key format changes only when Type-level only, no runtime break:
Open questions
🤖 Generated with Claude Code
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactionsWithout it, any mutation invalidates every cached `find` of every tenant, so a service where each row carries a `companyId` barely ever hits the cache. `scope` is one function branched on `context.method`: for `get`/ `find` it returns the scope the result is confined to, for mutations every scope the mutation may affect. The scope becomes the first key segment, so two tenants can never be served each other's entries. Safety is one-directional by construction. Whenever the scope cannot be determined — the resolver returned nothing usable or threw, `$select` stripped the field, a `patch` may move a row between tenants — the hook falls back to the behaviour it has without the option, so enabling `scope` never invalidates less than before. Every fallback emits a new `degrade` event, because the common fallback does not call `clear()` and would otherwise look exactly like a healthy scoped run. Also fixes three invalidation holes found while reworking the key parser: - an id containing `:` was truncated by the parser, never matched, and its cached `get` entry was never invalidated - a mutation whose result items partially lacked ids invalidated only the known ones and left the rest silently stale - the id `0` was treated as unknown and triggered a full wipe Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ReviewersNo reviewsUh oh!
There was an error while loading. Please reload this page. AssigneesNo one assignedLabels
None yet
ProjectsMilestoneNo milestoneDevelopmentSuccessfully merging this pull request may close these issues. Uh oh!
There was an error while loading. Please reload this page. 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. | |||||||||||||||||||||
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |