New Issue Checklist
Issue Description
LRUCache#put passes the per-entry TTL to lru-cache as a positional number, but lru-cache v11 takes it as a property of an options object. The number is silently ignored and the entry falls back to the cache-wide cacheTTL, so on the default in-memory adapter a per-entry TTL cannot be set at all.
// src/Adapters/Cache/LRUCache.js
put(key, value, ttl = this.ttl) {
this.cache.set(key, value, ttl); // v11 signature is set(key, value, { ttl })
}
LRUCache#set in v11 destructures its third argument, so a number contributes no properties and ttl resolves to the instance default set in the constructor.
Two related defects in the same path:
- The
LRUCache constructor never assigns this.ttl, so the ttl = this.ttl default in put is always undefined.
SubCache accepts a ttl in its constructor and stores it, but put() ignores this.ttl and forwards only the caller's argument. CacheController constructs all three sub-caches (role, user, graphQL) without a TTL anyway, so the parameter is unused.
The one caller in Parse Server that requests a per-entry TTL is ParseGraphQLController, which caches the GraphQL config for 60 seconds:
// src/Controllers/ParseGraphQLController.js
return this.cacheController.graphQL.put(this.configCacheKey, graphQLConfig, 60000);
On the in-memory adapter that entry actually lives for cacheTTL (5000ms by default), so the config is re-read from the database roughly 12 times more often than intended. RedisCacheAdapter#put honors the TTL correctly via PX, so the same call behaves differently depending on the configured cache adapter.
Steps to reproduce
Against lru-cache 11.2.7 as vendored:
const { LRUCache } = require('lru-cache');
const cache = new LRUCache({ max: 10, ttl: 5000 }); // cacheTTL default
cache.set('a', 1, 60000); // what LRUCache#put does today
cache.set('b', 1, { ttl: 60000 }); // v11 signature
console.log(cache.getRemainingTTL('a')); // 5000
console.log(cache.getRemainingTTL('b')); // 60000
Equivalently, through Parse Server: start a server with the default cache adapter, call config.cacheController.graphQL.put('k', 'v', 60000), wait longer than cacheTTL but less than 60 seconds, and get('k') returns null.
Actual Outcome
The per-entry TTL is discarded. Entries expire after the cache-wide cacheTTL.
Expected Outcome
The per-entry TTL is applied. A put with an explicit TTL keeps the entry for that duration, matching RedisCacheAdapter and the documented intent of the third parameter.
Environment
Server
- Parse Server version:
9.10.1-alpha.6
- Operating system:
macOS 15.5
- Local or remote host:
local
Database
- System (MongoDB or Postgres):
MongoDB
- Database version:
8.0
- Local or remote host:
local
Client
- SDK (iOS, Android, JavaScript, PHP, Unity, etc):
not applicable, server-internal cache
- SDK version:
not applicable
Logs
No error is produced. The TTL is dropped silently.
New Issue Checklist
Issue Description
LRUCache#putpasses the per-entry TTL tolru-cacheas a positional number, butlru-cachev11 takes it as a property of an options object. The number is silently ignored and the entry falls back to the cache-widecacheTTL, so on the default in-memory adapter a per-entry TTL cannot be set at all.LRUCache#setin v11 destructures its third argument, so a number contributes no properties andttlresolves to the instance default set in the constructor.Two related defects in the same path:
LRUCacheconstructor never assignsthis.ttl, so thettl = this.ttldefault inputis alwaysundefined.SubCacheaccepts attlin its constructor and stores it, butput()ignoresthis.ttland forwards only the caller's argument.CacheControllerconstructs all three sub-caches (role,user,graphQL) without a TTL anyway, so the parameter is unused.The one caller in Parse Server that requests a per-entry TTL is
ParseGraphQLController, which caches the GraphQL config for 60 seconds:On the in-memory adapter that entry actually lives for
cacheTTL(5000ms by default), so the config is re-read from the database roughly 12 times more often than intended.RedisCacheAdapter#puthonors the TTL correctly viaPX, so the same call behaves differently depending on the configured cache adapter.Steps to reproduce
Against
lru-cache11.2.7 as vendored:Equivalently, through Parse Server: start a server with the default cache adapter, call
config.cacheController.graphQL.put('k', 'v', 60000), wait longer thancacheTTLbut less than 60 seconds, andget('k')returnsnull.Actual Outcome
The per-entry TTL is discarded. Entries expire after the cache-wide
cacheTTL.Expected Outcome
The per-entry TTL is applied. A
putwith an explicit TTL keeps the entry for that duration, matchingRedisCacheAdapterand the documented intent of the third parameter.Environment
Server
9.10.1-alpha.6macOS 15.5localDatabase
MongoDB8.0localClient
not applicable, server-internal cachenot applicableLogs
No error is produced. The TTL is dropped silently.