You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Many API endpoints in EquipChain will query blockchain state through the Soroban SDK (Issue #3), which introduces network latency and RPC rate limits. To improve response times and reduce dependency on the Soroban network, a Redis caching layer should be implemented to store frequently accessed blockchain data with appropriate time-to-live (TTL) policies.
The caching layer must support the following operations: automatic caching of Soroban contract read results with configurable TTL (default 60 seconds for meter readings, 300 seconds for configuration data), cache invalidation when new data is written to the blockchain (write-through or write-behind patterns), cache warming for high-priority queries, and cache health monitoring with hit/miss metrics. The implementation should use the ioredis library for Redis connectivity with support for Redis Cluster and Sentinel for high availability in production.
A cache abstraction layer should be created to abstract Redis specifics from the business logic. This abstraction should expose a simple get(key), set(key, value, ttl), del(key), and flush(pattern) API. The cache keys should follow a consistent naming convention: equipchain:{entity}:{id}:{field} (e.g., equipchain:meter:device123:lastReading). The layer should gracefully handle Redis connection failures by falling back to direct Soroban queries without crashing the application.
Architecture: New src/services/cache.js providing the cache abstraction. New src/middleware/cache.js providing an Express middleware for automatic caching of GET responses. Integration with Soroban service to cache read results.
Impact: Significant performance improvement for read-heavy endpoints. Reduced load on Soroban RPC endpoints. Better user experience with faster response times. This is essential before launching any public-facing dashboard or API.
Create Cache Service: Write src/services/cache.js exporting a class CacheService. Constructor accepts Redis URL, connects with retry strategy (exponential backoff, max 10 retries). Methods: get(key), set(key, value, ttl), del(key), flush(pattern), health(). Use JSON serialization for complex objects. Handle connection errors gracefully with fallback logging.
Create Caching Middleware: Write src/middleware/cache.js exporting cache(ttl) that returns middleware. Before handler execution, check if request URL + query params match a cached key. If hit, return cached response directly. If miss, intercept the response to cache it before sending. Only cache GET requests. Vary cache key by authentication status.
Write Tests: Create tests/unit/cache.test.js with a Redis mock (or use a real Redis instance via Docker). Test get/set/del operations, TTL expiration, fallback behavior when Redis is down. Create tests/integration/cache.test.js testing the caching middleware with the Express app.
Description
Many API endpoints in EquipChain will query blockchain state through the Soroban SDK (Issue #3), which introduces network latency and RPC rate limits. To improve response times and reduce dependency on the Soroban network, a Redis caching layer should be implemented to store frequently accessed blockchain data with appropriate time-to-live (TTL) policies.
The caching layer must support the following operations: automatic caching of Soroban contract read results with configurable TTL (default 60 seconds for meter readings, 300 seconds for configuration data), cache invalidation when new data is written to the blockchain (write-through or write-behind patterns), cache warming for high-priority queries, and cache health monitoring with hit/miss metrics. The implementation should use the
ioredislibrary for Redis connectivity with support for Redis Cluster and Sentinel for high availability in production.A cache abstraction layer should be created to abstract Redis specifics from the business logic. This abstraction should expose a simple
get(key),set(key, value, ttl),del(key), andflush(pattern)API. The cache keys should follow a consistent naming convention:equipchain:{entity}:{id}:{field}(e.g.,equipchain:meter:device123:lastReading). The layer should gracefully handle Redis connection failures by falling back to direct Soroban queries without crashing the application.Technical Context & Impact
ioredis(^5.x). Redis server (Docker container from Issue [DevOps] Containerize Application with Docker Multi-Stage Build and Docker Compose #10). Environment variables:REDIS_URL(defaultredis://localhost:6379),REDIS_PASSWORD(optional),CACHE_DEFAULT_TTL(default 60).src/services/cache.jsproviding the cache abstraction. Newsrc/middleware/cache.jsproviding an Express middleware for automatic caching of GET responses. Integration with Soroban service to cache read results.Step-by-Step Implementation Guide
npm install ioredis. AddREDIS_URLto.envfile. Add theredisservice todocker-compose.yml(align with Issue [DevOps] Containerize Application with Docker Multi-Stage Build and Docker Compose #10).src/services/cache.jsexporting a classCacheService. Constructor accepts Redis URL, connects with retry strategy (exponential backoff, max 10 retries). Methods:get(key),set(key, value, ttl),del(key),flush(pattern),health(). Use JSON serialization for complex objects. Handle connection errors gracefully with fallback logging.src/middleware/cache.jsexportingcache(ttl)that returns middleware. Before handler execution, check if request URL + query params match a cached key. If hit, return cached response directly. If miss, intercept the response to cache it before sending. Only cache GET requests. Vary cache key by authentication status.readContract(), check cache before making RPC call. On successful read, store result in cache. On write operations, invalidate relevant cache keys.tests/unit/cache.test.jswith a Redis mock (or use a real Redis instance via Docker). Test get/set/del operations, TTL expiration, fallback behavior when Redis is down. Createtests/integration/cache.test.jstesting the caching middleware with the Express app.Verification & Testing Steps
redis-cliand verify cache keys exist with the naming conventionequipchain:*. Check TTL is set correctly.