Releases: Julien-R44/bentocache
[email protected]
What's Changed
- test: add testing documentation and improve test configuration by @thisisnkc in #90
- fix: crossslot issue by @Julien-R44 in #96
- fix(file): delete cache file if corrupted by @Julien-R44 in #97
- fix: support for cluster with bus by @Julien-R44 in #98
- Fix/lock timeout overrides timeout 0 by @Bnaya in #104
- Fix syntax for pulling products from cache by @jln-brtn in #102
- fix: standardize database credentials with environment variables and … by @thisisnkc in #100
New Contributors
- @thisisnkc made their first contribution in #90
- @Bnaya made their first contribution in #104
- @jln-brtn made their first contribution in #102
Full Changelog: https://github.com/Julien-R44/bentocache/compare/[email protected]@1.5.1
[email protected]
What's Changed
- Fix method name in documentation by @ZUHOWKS in #77
- feat: add cache hits metric layer label by @psimk in #76
- fix: enhance type support for CommonJS by @lzw1926 in #82
- feat: add
prune()method by @Julien-R44 in #85
New Contributors
- @ZUHOWKS made their first contribution in #77
- @psimk made their first contribution in #76
- @lzw1926 made their first contribution in #82
Full Changelog: https://github.com/Julien-R44/bentocache/compare/[email protected]@1.5.0
[email protected]
Minor Changes
- 2c5e4e7: Cleaner Worker Thread logs for the file driver now use the configured logger for better integration with structured logging systems
Patch Changes
Force Fresh + Namespace Clear fix
What's Changed
- feat: add
forceFreshoption by @Julien-R44 in #70 - fix: namespace clear doesn't use ioredis
keyPrefix+ namespace clear conflict by @ifullgaz in #68
New Contributors
Full Changelog: https://github.com/Julien-R44/bentocache/compare/[email protected]@1.3.0
Bugfixes
1.2.2
Patch Changes
- c932ac5: Disable TTL Autopurge of memory driver. It allows to avoid overflow errors when a TTL of +25 days is set. See issue #61 for more information.
- 0a2b25c: Fix
hasreturningtrueon entries previously deleted by tag (see #64). Thehasmethod now relies on the driver's internalgetmethod instead ofhas. This means the driver'shasimplementation is no longer used, and if you maintain a custom driver, you can safely remove it. - 6b01e1c: Fix knex driver throwing an error when quickly disconnecting from the database after application start. See adonisjs/cache#12 (comment)
- 73d25cd: Update clear method to use SCAN instead of KEYS for non-blocking. Also replace
delcommands withunlinksince this is non blocking.
What's Changed
- fix: update clear method to use SCAN instead of KEYS for non-blocking by @Maged-Zaki in #62
- fix:
hasreturningtrueon entries deletedByTag by @Julien-R44 in #65
New Contributors
- @Maged-Zaki made their first contribution in #62
Full Changelog: https://github.com/Julien-R44/bentocache/compare/[email protected]@1.2.2
Experimental tagging support and other goodies
Bentocache 1.2.0
The main feature of this release is experimental tagging support!
Documentation available here https://bentocache.dev/docs/tagging
If you encounter any bugs with tags, please report them via Github issues !
Minor Changes
-
8bb87b6: Add a new
expiremethod.This method is slightly different from
delete:When we delete a key, it is completely removed and forgotten. This means that even if we use grace periods, the value will no longer be available.
expireworks likedelete, except that instead of completely removing the value, we just mark it as expired but keep it for the grace period. For example:// Set a value with a grace period of 6 minutes await cache.set({ key: 'hello', value: 'world', grace: '6m', }) // Expire the value. It is kept in the cache but marked as STALE for 6 minutes await cache.expire({ key: 'hello' }) // Here, a get with grace: false will return nothing, because the value is stale const r1 = await cache.get({ key: 'hello', grace: false }) // Here, a get with grace: true will return the value, because it is still within the grace period const r2 = await cache.get({ key: 'hello' }) assert.deepEqual(r1, undefined) assert.deepEqual(r2, 'world')
-
d513fe2: Add a new
E_L2_CACHE_ERROR. Before this commit, error happening when interacting with the L2 cache were not wrapped in a custom error. This is now the case. If needed, you can still access the original error by using thecauseproperty of theE_L2_CACHE_ERRORerror.import { errors } from 'bentocache' try { await cache.getOrSet({ key: 'foo', factory: getFromDb(), }) } catch (err) { if (err instanceof errors.E_L2_CACHE_ERROR) { console.error('An error happened while interacting with the L2 cache', err.cause) } }
-
4d1feb5: Added a super simple circuit breaker system to the L2 Cache :
- a
l2CircuitBreakerDurationparameter to set the duration of the circuit breaker. How many seconds the circuit breaker will stay open. - If defined, the circuit breaker will open when a call to our distributed cache fails. It will stay open for
l2CircuitBreakerDurationseconds.
We may introduce more sophisticated circuit breaker system in the future, but for now, this simple system should be enough.
- a
-
6b1f42a: Enhance Factory Context by adding some new props.
await cache.getOrSet({ key: 'foo', factory: (ctx) => { // You can access the graced entry, if any, from the context if (ctx.gracedEntry?.value === 'bar') { return 'foo' } // You should now use `setOptions` to update cache entry options ctx.setOptions({ tags: ['foo'], ttl: '2s', skipL2Write: true, }) return 'foo' }, })
setTtlhas been deprecated in favor ofsetOptionsand will be removed in the next major version. -
73ac0fa: Add experimental tagging support. See #53
await bento.getOrSet({ key: 'foo', factory: getFromDb(), tags: ['tag-1', 'tag-2'], }) await bento.set({ key: 'foo', tags: ['tag-1'], })
Then, we can delete all entries tagged with tag-1 using:
await bento.deleteByTags({ tags: ['tag-1'] })
As this is a rather complex feature, let's consider it experimental for now. Please report any bugs on Github issues
-
6b1f42a: Add
skipL2WriteandskipBusNotifyoptions.await cache.getOrSet({ key: 'foo', skipL2Write: true, skipBusNotify: true, factory: () => 'foo', })
When enabled,
skipL2Writewill prevent the entry from being written to L2 cache, andskipBusNotifywill prevent any notification from being sent to the bus. You will probably never need to use these options, but they were useful for internal code, so decided to expose them. -
b9db3b5: Rework the logs issued by bentocache to make them much cleaner, more consistent and make debug easier
Patch Changes
- 491d12e: Handle deleteMany with empty keys list
[email protected]
This release primarily brings some huge performance boosts along with a few new features. Simply by installing this new version, you can enjoy up to 15x higher throughput in certain caching scenarios without any additional action required.
In some benchmarks of super common caching use-cases, we are up to 160x faster than cache-manager, the most popular caching library in Node.js ecosystem :
┌──────────────────────────────────┬────────────────────────┬─────────┐
│ Task name │ Throughput med (ops/s) │ Samples │
├──────────────────────────────────┼────────────────────────┼─────────┤
│ 'L1 GetOrSet - BentoCache' │ '1062699 ± 20724' │ 168254 │
│ 'L1 GetOrSet - CacheManager' │ '5702 ± 176' │ 1040 │
│ 'L2 GetOrSet - BentoCache' │ '1823 ± 64' │ 347 │
│ 'L2 GetOrSet - CacheManager' │ '1455 ± 38' │ 282 │
│ 'Tiered GetOrSet - BentoCache' │ '1072961 ± 11637' │ 174603 │
│ 'Tiered GetOrSet - CacheManager' │ '5876 ± 80' │ 1089 │
│ 'Tiered Get - BentoCache' │ '1949318 ± 37272' │ 1805048 │
│ 'Tiered Get - CacheManager' │ '531350 ± 7789' │ 496805 │
│ 'Tiered Set - BentoCache' │ '2171 ± 45' │ 2143 │
│ 'Tiered Set - CacheManager' │ '2211 ± 84' │ 2159 │
└──────────────────────────────────┴────────────────────────┴─────────┘You can see the benchmarks here
New Features
-
07224ba: Add two new functions in the factory callback context:
cache.getOrSet({ key: 'foo', factory: ({ skip, fail }) => { const item = await getFromDb() if (!item) { return skip() } if (item.isInvalid) { return fail('Item is invalid') } return item }, })
-
Returning
skipin a factory will not cache the value, andgetOrSetwill returnsundefinedeven if there is a stale item in cache.
It will force the key to be recalculated on the next call. -
Returning
failin a factory will not cache the value and will throw an error. If there is a stale item in cache, it will be used.
-
-
2578357: Added a
serialize: booleanoption to the memory driver.If false, It means the data stored in the memory cache will not be serialized/parsed using
JSON.stringifyandJSON.parse. This allows for a much faster throughput but at the expense of:- not being able to limit the size of the stored data, because we can't really know the size of an unserialized object
- Having inconsistent return between the L1 and L2 cache. The data stored in the L2 Cache will always be serialized because it passes over the network. Therefore, depending on whether the data is retrieved from the L1 and L2, we can have data that does not have the same form. For example, a Date instance will become a string if retrieved from the L2, but will remain a Date instance if retrieved from the L1. So, you should put extra care when using this feature with an additional L2 cache.
🔗 https://bentocache.dev/docs/cache-drivers#serialize-option
v1.0.0
Upgrade Guide 1.0.0
Breaking Changes
Remove old syntax
We removed the "legacy" syntax and only keep the POJO-one.
For each method, the method signature is a full object, for example :
bento.get({ key: 'foo '})timeouts
Previously you could define your timeouts like { soft: '200ms', hard: '2s' }. Now you should use the timeout and hardTimeout options like this:
getOrSet({ timeout: '200ms', hardTimeout: '2s' })You can now also use 0 for timeout which means that, if a stale value is available, then it will be returned immediately, and the factory will run in the background. SWR-like, in short.
Default soft timeout
Now, the default timeout is 0. As explained above, this enables the SWR-like behavior by default, which is a good default for most cases and what most people expect. So make sure to update your code if you were relying on the previous default.
gracePeriod
gracePeriodis nowgraceand should be eitherfalseor aDuration.- If you were using the
fallbackDurationoption, you should now use thegraceBackoffoption at the root level.
suppressL2Errors
Previously, suppressL2Errors was automatically enabled even when we had just a L2 layer. Which can be confusing, because errors were filtered out. See #25
Now suppressL2Errors is a bit more intelligent and will only be enabled if you have a L1 layer. Unless you explicitly set it to true.
undefined values
Now, undefined values are forbidden in the cache. If you are trying to cache undefined, an error will be thrown. This is a breaking change because it was previously allowed.
If you want to cache something to represent the absence of a value, you can use null instead of undefined.
New Features
onFactoryError
Added an onFactoryError option that allows to catch errors that happen in factories, whether they are executed in background or not.
const result = await cache.getOrSet({
key: 'foo',
grace: '5s',
factory: () => {
throw new MyError()
},
onFactoryError: (error) => {
// error is an instance of errors.E_FACTORY_ERROR
// error.cause is the original error thrown by the factory
// you can also check if the factory was executed in background with error.isBackgroundFactory
// and also get the key with error.key. Will be `foo` in this case
},
})Memory driver options
The memory driver can now accept maxSize and maxEntrySize in human format. For example, maxSize: '1GB' or maxEntrySize: '1MB'.
We use https://www.npmjs.com/package/bytes for parsing so make sure to respect the format accepted by this module.
Re-worked the logic when only L2 is enabled
Previously, we were using a single piece of code to handle both scenarios, where only L2 is enabled and where both L1 and L2 are enabled. This was a bit confusing and led to some bugs.
Now, we have a clear separation between the two cases and we could fix some bugs that were present when only L2 was enabled.
[email protected]
Commits
- refactor: Only one bus instance per named cache. All subsequent namespaces under it use the same bus. (3813247)
- fixed return type for CacheStack namespace function (c772f83)
- optimize: added namespace cache to CacheStack to avoid unnecessary creation of caches and buses (eaef9d8)
- fix: clear message goes to all bus instances since channel name is the same (1699fe6)
What's Changed
Full Changelog: https://github.com/Julien-R44/bentocache/compare/[email protected]@1.0.0-beta.12
[email protected]
What's Changed
Full Changelog: https://github.com/Julien-R44/bentocache/compare/[email protected]@1.0.0-beta.11