Julien-R44 / bentocache

🍱 Bentocache is a robust multi-tier caching solution for Node.js applications
https://bentocache.dev
MIT License
394 stars 9 forks source link

With a bus, `clear`ing a namespace will clear the entire cache #32

Closed sroze closed 3 weeks ago

sroze commented 2 months ago

Unless I'm mistaken, when publishing the Clear message to the bus, we are not providing it with the namespace name (https://github.com/Julien-R44/bentocache/blob/9d66e2f14c41936493d7af6b1d23a14c44bdb192/packages/bentocache/src/cache/cache.ts#L255) and as such, all subscribed caches (including the root) will clear the cache (https://github.com/Julien-R44/bentocache/blob/9d66e2f14c41936493d7af6b1d23a14c44bdb192/packages/bentocache/src/bus/bus.ts#L65); right?

wodCZ commented 2 months ago

Based on my testing, publishing clear on a namespace in instanceB correctly clears just the provided namespace (in Redis, not sure about l1).

However, in instanceA the l1 cache of the namespace is not invalidated, and stale results are returned until the original ttl is reached.

Not sure whether this is dependent on the configuration, sharing mine in case it's an edge-case:

        const url = new URL(configService.get('redisUrl'));
        const connection = {
          host: url.hostname,
          port: Number(url.port),
          username: url.username,
          password: url.password,
          tls: url.protocol === 'rediss:' ? { requestCert: true } : undefined,
          db: 1, // use db 1 for cache, 0 is used by bull}}))
        };
        const cache = new TieredCache({
          default: 'cache',
          gracePeriod: {
            enabled: true,
            duration: '1h',
            fallbackDuration: '1m',
          },
          ttl: '1m',
          timeouts: { soft: '500ms' },
          earlyExpiration: 0.8,
          stores: {
            cache: bentostore()
              .useL1Layer(memoryDriver({ maxSize: 100_000_000 }))
              .useL2Layer(redisDriver({ connection }))
              .useBus(redisBusDriver({ connection })),
          },
          logger: PinoLogger.root,
        });

(TieredCache is just a wrapper for easier NestJS DI integration:

@Injectable()
export class TieredCache extends BentoCache<{
  cache: ReturnType<typeof bentostore>;
}> {}

This is unfortunately a deal-breaker for me, since I have a read-only clientside and read-write admin instance which should be able to invalidate the clientside cache whenever a change is made (pretty common use-case IMO?).

@Julien-R44 I've noticed your recent Sponsorship program (congrats!) and I suppose you're busy building Tuyau (or just enjoying the summer). Would you mind sharing an insight on whether you plan to work on bentocache in the near future? Would sponsoring help getting this issue fixed?

Thanks in advance 🙏

Julien-R44 commented 3 weeks ago

Sorry I slept on this issue for a long time. Indeed, it's been quite a busy summer 😄