parse-community / parse-community/parse-server
Per-entry cache TTL is silently ignored by the in-memory cache adapter
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 21.4k
- Forks
- 4.8k
- Avg merge
- 7h 45m
- Merged PRs (30d)
- 11
Description
New Issue Checklist
- Report security issues confidentially.
- Any contribution is under this license.
- Before posting search existing issues.
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
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:
// 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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/Adapters/Cache/LRUCache.js and compare its put path with RedisCacheAdapter#put and the lru-cache v11 signature. Trace the 60000ms call in src/Controllers/ParseGraphQLController.js and the SubCache and CacheController construction described in the issue. Done means explicit per-entry TTLs work in the in-memory adapter, default and sub-cache TTL behavior is consistent, and the GraphQL cache no longer expires at cacheTTL.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- graphql, javascript, node.js
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100