Módulo Cache
O módulo cache fornece um sistema de cache distribuído para scripts Lua. O cache suporta operações de leitura/escrita com expiração automática (TTL) e mecanismos de sincronização para operações concorrentes.
O sistema de cache é especialmente útil para:
- Armazenar resultados de operações caras (como requisições HTTP, consultas de banco de dados)
- Evitar chamadas redundantes a APIs externas
- Sincronizar múltiplos workers que tentam acessar o mesmo recurso simultaneamente
- Compartilhar dados entre diferentes scripts Lua em execução
Funções Disponíveis
cache.put(key, value, ttl)
Armazena um valor no cache com um tempo de vida específico.
Parâmetros:
-
key(string): Chave única para identificar o valor no cache -
value(qualquer tipo Lua): Valor a ser armazenado (pode ser string, número, tabela, booleano, etc.) -
ttl(number): Time To Live em segundos - quanto tempo o valor permanecerá no cache
Valor de retorno:
-
nilem caso de sucesso - Lança erro em caso de falha
Exemplo:
-- Armazenar um resultado de API por 5 minutos (300 segundos)
local resultado_api = {status = "ativo", usuarios = 150}
cache.put("status_sistema", resultado_api, 300)
-- Armazenar uma string simples por 1 hora
cache.put("ultima_atualizacao", "2026-01-15T10:30:00Z", 3600)
-- Armazenar um número
cache.put("contador_requisicoes", 42, 60)
cache.get(key)
Recupera um valor do cache.
Parâmetros:
-
key(string): Chave do valor a ser recuperado
Valor de retorno:
- O valor armazenado se existir e não estiver expirado
-
nilse a chave não existir ou o valor tiver expirado
Exemplo:
-- Recuperar um valor do cache
local status = cache.get("status_sistema")
if status then
print("Status do sistema:", status.status)
print("Usuários ativos:", status.usuarios)
else
print("Cache expirado ou não encontrado")
-- Fazer uma nova requisição para obter os dados
end
-- Verificar se um valor existe
local ultima_atualizacao = cache.get("ultima_atualizacao")
if ultima_atualizacao then
print("Última atualização:", ultima_atualizacao)
end
cache.mark_pending(key)
Marca uma chave como "pendente". Esta função é usada para sincronizar múltiplos workers que tentam calcular o mesmo valor simultaneamente.
Parâmetros:
-
key(string): Chave a ser marcada como pendente
Valor de retorno:
-
nilem caso de sucesso - Lança erro em caso de falha
Comportamento:
- Quando uma chave é marcada como pendente, qualquer chamada subsequente a
cache.get()para essa chave irá bloquear até que um valor seja armazenado comcache.put() - O estado "pendente" expira automaticamente após 5 minutos (300 segundos)
- Útil para evitar que múltiplos workers recalculem o mesmo valor caro simultaneamente
Exemplo:
-- Padrão típico para evitar cache stampede
local function obter_dados_caros(chave)
-- Primeiro tenta obter do cache
local dados = cache.get(chave)
if dados then
return dados
end
-- Se não encontrou, marca como pendente
local sucesso, erro = pcall(cache.mark_pending, chave)
if not sucesso then
-- Outro worker já marcou como pendente, espera pelo resultado
dados = cache.get(chave) -- Esta chamada irá bloquear até o valor estar disponível
if dados then
return dados
end
end
-- Este worker é responsável por calcular o valor
-- ... cálculo caro aqui ...
local resultado = calcular_dados_caros()
-- Armazena no cache para outros workers
cache.put(chave, resultado, 300)
return resultado
end
cache.delete(key)
Remove uma chave do cache imediatamente.
Parâmetros:
-
key(string): Chave a ser removida
Valor de retorno:
-
nilem caso de sucesso - Lança erro em caso de falha
Exemplo:
-- Remover um valor específico
cache.delete("dados_expirados")
-- Limpar cache relacionado a um usuário
cache.delete("usuario_123_perfil")
cache.delete("usuario_123_preferencias")
cache.delete("usuario_123_historico")
Informações Adicionais
Sincronização de Workers
O mecanismo de "pendente" permite que múltiplos workers sincronizem o cálculo de valores caros:
- Primeiro worker marca a chave como pendente e calcula o valor
- Outros workers que tentam acessar a mesma chave aguardam o resultado
- Quando o primeiro worker termina, armazena o valor e todos os workers recebem
Tipos de Dados Suportados
O cache pode armazenar qualquer tipo de valor Lua suportado pelo sistema de serialização do Monsta, incluindo:
- Strings
- Números
- Booleanos
- Tabelas
- Valores nulos
Considerações de Performance
- Acesso rápido: Operações de cache são muito mais rápidas que recalcular valores ou fazer requisições externas
- Memória: O cache é mantido em memória, então valores muito grandes podem impactar a performance
- Concorrência: O sistema é thread-safe e suporta acesso concorrente de múltiplos workers
- Network: O cache é local ao processo, não há overhead de rede
Limitações
- Volátil: Dados são perdidos se o processo for reiniciado
- Memória limitada: Não use para armazenar grandes volumes de dados
- Distribuição: Este é um cache local, não distribuído entre múltiplos servidores
Melhores Práticas
- TTL adequado: Use TTLs apropriados para o tipo de dado (curto para dados dinâmicos, longo para dados estáticos)
- Chaves descritivas: Use nomes de chave que descrevam claramente o conteúdo
-
Namespace: Use prefixos para organizar chaves (ex:
api_,user_,config_) - Fallback: Sempre tenha um fallback caso o cache esteja vazio ou expirado
-
Invalidação: Use
delete()para invalidar cache quando dados mudarem