Table of Contents

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:tree iz dve aplikacije bio isti ključ — i jedna bi čitala tuđe podatke. Takođe omogućava SCAN 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.

factory se 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.