Class CacheService
- Namespace
- UsluzionicaServer.Infrastructure.Redis
- Assembly
- UsluzionicaServer.dll
Tanak sloj nad Redis-om za keširanje objekata.
Cela poenta ove klase je da pozivaoci NIKAD ne pišu try/catch oko keša. Svaka metoda ovde guta grešku i ponaša se kao promašaj:
• Redis mrtav pri čitanju → vrati null → pozivalac ide u bazu • Redis mrtav pri upisu → tiho ništa → sledeći zahtev opet ide u bazu
Rezultat je da gašenje Redis-a čini aplikaciju SPORIJOM, ne pokvarenom. Vidi RedisConnection za detalje.
Zašto ručno preko IDatabase, a ne IDistributedCache: IDistributedCache interfejs vraća bajtove i nema pojam o obrascu „uzmi ili izračunaj", pa bi se ista try/catch logika ponavljala na svakom pozivnom mestu.
public sealed class CacheService
- Inheritance
-
CacheService
- Inherited Members
Constructors
- CacheService(RedisConnection, ILogger<CacheService>)
Tanak sloj nad Redis-om za keširanje objekata.
Cela poenta ove klase je da pozivaoci NIKAD ne pišu try/catch oko keša. Svaka metoda ovde guta grešku i ponaša se kao promašaj:
• Redis mrtav pri čitanju → vrati null → pozivalac ide u bazu • Redis mrtav pri upisu → tiho ništa → sledeći zahtev opet ide u bazu
Rezultat je da gašenje Redis-a čini aplikaciju SPORIJOM, ne pokvarenom. Vidi RedisConnection za detalje.
Zašto ručno preko IDatabase, a ne IDistributedCache: IDistributedCache interfejs vraća bajtove i nema pojam o obrascu „uzmi ili izračunaj", pa bi se ista try/catch logika ponavljala na svakom pozivnom mestu.
Fields
- Prefix
Prefiks za SVE ključeve ove aplikacije.
Bitno jer se Redis instanca u praksi deli između projekata. Bez prefiksa bi
categories:treeiz dve aplikacije bio isti ključ — i jedna bi čitala tuđe podatke. Takođe omogućavaSCAN usluzionica:*pri debagovanju.
Methods
- GetAsync<T>(string)
Čita i deserijalizuje. Vraća null i pri promašaju i pri grešci.
- GetOrSetAsync<T>(string, TimeSpan, Func<Task<T>>)
Glavni obrazac: vrati iz keša, ili izračunaj i zapamti.
factoryse poziva SAMO pri promašaju. Namerno NE postoji zaključavanje oko njega: ako dva zahteva istovremeno promaše, oba će otići u bazu i oba upisati isti rezultat. To je prihvatljivo za podatke koje keširamo (kategorije, profili) — a lock bi ovde bio distribuirani lock po ključu, što je više složenosti nego što jedan suvišan SELECT vredi.
- RemoveAsync(string)
Briše jedan ključ — poziva se kad se podatak promeni.
- RemoveByPrefixAsync(string)
Briše sve ključeve po šablonu, npr.
provider:*.Koristi SCAN, ne KEYS. KEYS blokira ceo Redis dok prolazi kroz sve ključeve — na produkcijskoj instanci to je zastoj koji se vidi. SCAN ide u komadima i pušta druge komande između.
- SetAsync<T>(string, T, TimeSpan)
Serijalizuje i upisuje sa TTL-om. Greška se tiho ignoriše.