arcjet-js
arcjet-js copied to clipboard
feat(arcjet): Segment cache entries by rule
This changes the way caching is done in the SDK. Instead of a single top-level block cache for a decision, we will now cache each rule result with a DENY conclusion. These are cached on a combination of ruleId and (per rule) fingerprint. If a decision is made by the Decide service, it will return the ruleId and fingerprint to store in the cache.
This means that all rules will now have a local component, even if it is just looking up a value in the cache.
Depends upon #4209
😎 Merged successfully - details.
This will get rebased on top of #4204
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
| Diff | Package | Supply Chain Security |
Vulnerability | Quality | Maintenance | License |
|---|---|---|---|---|---|---|
| @arcjet/cache@1.0.0-beta.7 |
Been waiting on this pr to be merged. Any updates??
We’re almost there @developedbynick ! We’re aiming for the next week or so.
using the cache would need to put any calls that could throw in try / catch blocks
We already try/catch around rule execution, which is where my explanation of "Errored" results comes from. We need to do everything in our power to not produce errors for users (see below).
prefer to have invariants enforced by clear signals that the contract has been violated and that some part of the runtime may be in an error or undefined state.
I think I'd rather just accept empty strings than calling these invariants and throwing. This is a footgun for users but I really don't want to throw in this code.
In this case, that could also be achieved by defining a type guard on the get / set methods to ensure that the namespaces and other values that must be set are so marked in the types.
As I've documented in internal documentation, we need to treat usage of TypeScript as raw JavaScript so we can't rely exclusively on a TypeScript type to ensure anything here.
In this case, that could also be achieved by defining a type guard on the get / set methods to ensure that the namespaces and other values that must be set are so marked in the types.
As I've documented in internal documentation, we need to treat usage of TypeScript as raw JavaScript so we can't rely exclusively on a TypeScript type to ensure anything here.
This is a good requirement for code that is user-facing, but users do not access the MemoryCache instances directly themselves, correct?
The distinction I'm drawing here is between actual exceptions and runtime errors. For runtime errors, as embedded code writers, we should be following the Robustness Principle (which is more or less what the existing documents stipulate). I'm arguing that the the "must nots" in the code comments should be treated as preconditions / invariants in the design-by-contract sense, and that violations of those invariants should be treated as actual exceptions, which is to say situations in which the system is in an inconsistent state. I want to ensure that we catch all possible instances of this during development, using whatever means are available to us to enforce our API contracts. I don't want this to bubble up to end users. As long as we're confident in the strategies we're using to achieve that goal, I am agnostic as to what strategies we choose to use.
To me, putting type guards on components that are used internally is one way to do that, because, as per the guidelines you've written, end users are running transpiled "raw" JS.
This is a good requirement for code that is user-facing, but users do not access the MemoryCache instances directly themselves, correct?
They can, if they Write a Custom Rule.
The distinction I'm drawing here is between actual exceptions and runtime errors.
This is a good distinction. With the implementation I ended up using for the namespaced MemoryCache, there's nothing actually stopping users from using empty namespaces or keys (it's just another value in a Map) so I've removed that restriction and instead just throw if non-strings are provided, which are also encoded in TypeScript.
Thanks Guys. I screamed out "yes" when I saw the merge😂😂
@developedbynick expect an SDK release by the end of the week 🚀
Thanks David!