Skip to content

feature: configure redis cache for high traffic endpoints #103

@loudsheep

Description

@loudsheep
  • zainstalować ioredis - co prawda BullMQ już z tego korzysta jako dependency, ale teraz będze korzystany otwarcie xd
  • kowe zmienne środowiskowe w .env.example oraz walidacja w Joi w app.module.ts
    • REDIS_CACHE_TTL_SHORT z default na 30 sekund
    • REDIS_CACHE_TTL_LONG z default na 10 minut
  • moduł cache - bez kotrolera, tylko service. **ważne: ** powinien być globalny bo będzie używany w kilku miejscach w apce
  • storzyć serice cache który inicjalicuje redisa w construktorze (korzysta z tyc samych danych logowania z .env jak system kolejkowania)
this.client = new Redis({
    host:     config.getOrThrow<string>("REDIS_HOST"),
    port:     config.getOrThrow<number>("REDIS_PORT"),
    username: config.get<string>("REDIS_USER"),
    password: config.get<string>("REDIS_PASS"),
    db:       1,  // db 0 is reserved for BullMQ
    lazyConnect: true,
});

ta wartość db: 1 jest dlatego że BullMQ domyślnie używa db: 0 - cache idzie na db: 1 żeby klucze kolejki i cache'a były w osobnych przestrzeniach na tej samej instancji Redisa

  • dodać trzy metody w tym serwisie: get<T>(key), set(key, value, ttl), invalidateByPrefix(prefix) z czego ta ostatni nie powinna używać KEYS tylko SCAN + DEL (bo keys blokuje wątek redisa i na produkcji to nie zbyt porządane, chodziaż przy naszej skali nie powinno być problemu)
  • CacheService powinien implementować OnModuleDestroy i w metodzie onModuleDestroy() wywołać await this.client.quit() - żeby przy zamykaniu aplikacji (restart contenera/deploy) połączenie było gracefull zamykane a nie zrywane
  • OPTIONAL: to bardziej taki quality of life dla łatości używania tego potem. można dodać cache.keys.ts plik w tym module i tam poprostu takie helpery to stworzenia klucza w redis na podstawie jakiś uuid czyy innych. np: publicEvent(slug), publicEventListing(queryHash), publicForm(slug, formId), publicBlockTree(slug, attributeUuid), publicBlockParticipants(slug, attributeUuid, blockUuid) <-- to tylko przykłady, bo wydaje mi się że takie będzimyy użyywać, ale to absolutnie nie jest sztywne

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

Status

Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions