CoreLib Caching Design Reference
Keyworks: Caching Redis Expiration
Conceitos
Caching Service
Serviço disponibilizado pelo tipo Primavera.Core.Caching.ICachingService que fornece as funcionalidades de cache.
Cache
Espaço de armazenamento de objetos.
Cache Item
Elemento armazenado em cache identificado por chave. A chave é única dentro da região.
Expiration
Define a validade de um cache item através da definição do momento em que o cache item expira. Existem dois mecanismos de expiração disponíveis:
- Absolute: Define do momento exato em que o cache item expira.
- Sliding: Define o tempo de validade de um item após a última utilização.
A combinação dos dois métodos é possível. O resultado é que a validade do cache item vai aumentando a cada acesso até atingir a expiração absoluta.
Redis
"Redis is an open source (BSD licensed), in-memory data structure store, used as database, cache and message broker. It supports data structures such as strings, hashes, lists, sets,sorted sets with range queries, bitmaps, hyperloglogs and geospatial indexes with radius queries. Redis has built-in replication, Lua scripting, LRU eviction, transactions and different levels of on-disk persistence, and provides high availability via Redis Sentinel and automatic partitioning with Redis Cluster."
Cache Redis do Azure
A cache Redis do Microsoft Azure baseia-se no conhecido software open-source Cache Redis. Oferece acesso a uma cache Redis seguro e dedicado, gerenciado pela Microsoft, proporcionando o melhor de dois mundos: os recursos avançados e o ecossistema do Redis e a hospedagem e o monitoramento da Microsoft.
Desenho
Arquitetura
O Caching Service é um componente que disponibiliza uma implementação de um serviço de caching, configurável, que pode ser usado nas aplicações.

ICachingService
Interface público do caching service que abstrai a implementação concreta de cada uma das caches utilizadas na aplicação.
CachingServiceFactory
Componente que é capaz de criar instâncias do caching service a partir de configuração. A configuração define as características da cache gerida pelo caching service.
DefaultCachingService
Implementação por defeito do caching service que utiliza um ICachingHandler para armazenar os dados na cache.
ICachingHandler
Componente que gere o armazenamento dos cache items na cache e que, por isso, dita parte fundamental das características da cache gerida pelo caching service.
Comportamento
Uma aplicação pode gerir tantas caches quantas necessárias, sendo cada uma suportada por implementações iguais ou diferentes, dependendo da configuração.
Por defeito, uma aplicação terá disponível 2 caches:
- PerProcess: os dados da cache são partilhados dentro do processo da aplicação.
- PerApplication: os dados da cache são partilhados por vários processos da aplicação.
De resto, podem ser configurados tantos outros serviços de caching quantos forem necessários à aplicação.

Determinada instância do caching service pode ser obtida usando a CachingServiceFactory.
As duas caches por defeito estão são disponíveis:
ICachingService service1 = CachingServiceFactory.PerProcess();
ICachingService service2 = CachingServiceFactory.PerApplication();
Outras caches podem ser registadas no ficheiro de configuração e acedidas também através da factory:
ICachingService service3 = CachingServiceFactory.Initialize("mycache");
ICachingService service4 = CachingServiceFactory.Initialize(configuration);
Deste modo, o caching service permite a organização dos cache items em dois níveis, em primeiro lugar por cache e, dentro da cache, por region. Cada cache item tem uma chave que é única dentro da sua região.
Não existem restrições quanto aos tipos dos valores guardados em cada cache item, sendo apenas indispensável que o tipo seja serializável para que sejam suportadas implementações distribuídas que necessitem de armazenar noutros suportes para além da memória ou que necessitem de transmitir os cache items pela rede.
Configuração
Como foi referido anteriormente, cada cache pode definida por configuração, tanto em runtime, através da
classe CachingServiceConfiguration, como em design-time, no ficheiro de configuração, através da secção
de configuração CachingServiceConfigurationSection.
<configSections>
<section name="cachingServiceConfiguration" type="Primavera.Core.Caching.CachingServiceConfigurationSection, Primavera.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=33086db60a481256" />
</configSections>
<cachingServiceConfiguration>
<elements>
<add name="default">
<caches>
<add name="cache-perprocess" handlerType="Primavera.Core.Caching.InProcess.DictionaryCacheHandler, Primavera.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=33086db60a481256" />
<add name="cache-perapplication" handlerType="Primavera.Core.Caching.Redis.RedisCacheHandler, Primavera.CoreLib.Caching.Redis, Version=4.0.0.0, Culture=neutral, PublicKeyToken=33086db60a481256">
<settings>
<add key="Redis.Host" value="jasmin.redis.cache.windows.net:6380" />
<add key="Redis.Password" value="p4hP59CgnzpgO9m9TpDjqoBVk94J3xt1qiNnu6qfIkc=" />
<add key="Redis.ConnectionTimeout" value="00:00:03" />
<add key="Redis.UseSsl" value="true" />
<add key="Redis.AllowAdminOperations" value="true" />
<add key="Redis.DefaultDatabaseIndex" value="0" />
<add key="Redis.MaxNumberOfDatabases" value="100" />
<add key="DefaultExpiryMode" value="Absolute" />
<add key="DefaultTimeout" value="00:01:00" />
<add key="EnableStatistics" value="true" />
<add key="RecordTracing" value="true" />
<add key="UseRootTracing" value="false" />
<add key="RetryTimes" value="2" />
<add key="RetryBackoff" value="00:00:00.100" />
</settings>
</add>
</caches>
</add>
</elements>
</cachingServiceConfiguration>
Notem-se os seguintes aspetos:
- Cada cache é identificada por um nome. Esse é o nome que deve ser utilizado como parâmetro do método
CachingServiceFactory.Initialize(). - As duas caches por defeito, PerProcess e PerApplication, são sempre identificadas pelos nomes "cache-perprocess" e "cache-perapplication".
- A implementação de cada uma das caches é determinada pelo "handlerType".
- Cada tipo de cache terá as suas configurações próprias, definidas no elemento "settings".
Configurações disponíveis
DefaultExpiryMode- define o modo de expiração por defeito dos cache items. O valor por defeito éExpiryMode.Default.DefaultTimeout- define o timeout por defeito para todos os cache items cuja política de expiração não esteja definida. O valor pode feito é infinito (ou seja, os items não expiram).EnableStatistics- indica se o serviço deve registar estatísticas de utilização do serviço.RecordTracing- indica se o serviço deve registar informação de tracing.UseRootTracing- indica se o serviço de tracing utilizado deve ser o de root.RetryTimes- define o número de vezes que determinada operação deve ser executada em caso de erro. O valor por defeito é 3.RetryBackoff- define o tempo de espera entre novas tentativas de execução de uma operação em caso de erro. O valor pode feito é 200 ms.Redis.Host- define o endereço do servidor Redis.Redis.Password- define a password de acesso ao servidor Redis.Redis.ConnectionTimeout- define o timeout na conexão ao servidor Redis. O valor por defeito é 5 s.Redis.UseSsl- indica se a conexão ao servidor Redis deve utilizar SSL.Redis.AllowAdminOperations- indica se as operações de administração são permitidas no servidor Redis.Redis.DefaultDatabaseIndex- define o índica da base de dados por defeito. O valor por defeito é 0.Redis.MaxNumberOfDatabases- define o número máximo de bases de dados no servidor Redis. O valor por defeito é 200.
Implementações
Na versão atual da CoreLib estão disponíveis os seguintes tipos de caches (implementações de ICachingHandler):
PerProcess (Dictionary)
Tipo: Primavera.Core.Caching.InProcess.DictionaryCacheHandler
Implementação que utiliza um ConcurrentDictionary para armazenar os cache items.
Sendo uma implementação em memória, apenas permite a partilha de dados num único processo da aplicação.
PerProcess (MemoryCache)
Tipo: Primavera.Core.Caching.InProcess.MemoryCacheHandler
Implementação que utiliza o componente System.Runtime.Caching.MemoryCache para armazenar os cache items.
Sendo uma implementação em memória, apenas permite a partilha de dados num único processo da aplicação.
PerApplication (Redis)
Tipo: Primavera.Core.Caching.Redis.RedisCacheHandler
Implementação que utiliza um serviço Redis para armazenar os cache items. Sendo uma implementação distribuída, permite a partilha de dados entre processos distintos da aplicação.
Questões em Aberto
N/A
FAQ
- P: Que configurações são necessárias para utilizar o Caching Service?
- R: Devem ser definidas duas caches, com os nomes "cache-perprocess" e "cache-perapplication".
- P: Se pretender configurações diferentes das definidas por omissão?
- R: Deve definir as configurações no ficheiro de configuração da aplicação.
- P: Como se criam named regions?
- R: As named regions não têm nenhum método de criação, são criadas à medida que são usadas nos parâmetros do serviço.
- P: Que requisitos são necessárias para garantir que o meu objecto é serializavel em
cenário de caching Redis?
- R: O objecto deve ser um ser serializavel para JSON. A componente usada para serialização pelo sistema é o Newtonsoft.Json.