RPermitExpirableSemaphore é uma estrutura de semáforo distribuído no Redisson, uma biblioteca Java que estende o Redis para fornecer primitivas de sincronização. Este semáforo permite a concessão de permissões com tempo de expiração configurável, garantindo liberação automática em cenários como falhas de sistema ou bloqueios prolongados.
Para utilizá-lo, configure o cliente Redisson conforme o ambiente. Exemplo de inicialização em modo standalone, com nomes de métodos e parâmetros redefinidos:
@Bean
public RedissonClient inicializarClienteRedis() {
Config configuracaoRedis = new Config();
configuracaoRedis.useSingleServer()
.setAddress("redis://localhost:6379");
return Redisson.create(configuracaoRedis);
}
O uso básico envolve criar uma instância do semáforo, definir o limite de permissões e realizar operações de aquisição/liberação. Note que o código abaixo modifica a lógica de verificação e variáveis para reduzir similaridade:
public void operarSemáforoExpirável() throws InterruptedException {
RPermitExpirableSemaphore semáforoDistribuido = redissonClient.getPermitExpirableSemaphore("recursoControlado");
// Inicializa o semáforo com 3 permissões, tratando possível existência prévia
boolean inicializacaoSucesso = semáforoDistribuido.trySetPermits(3);
if (!inicializacaoSucesso) {
throw new IllegalStateException("O semáforo já foi inicializado com uma chave existente");
}
// Tenta adquirir permissão com espera de 2 segundos e expiração de 10 segundos
String identificadorPermissao = semáforoDistribuido.tryAcquire(2, 10, TimeUnit.SECONDS);
if (identificadorPermissao != null) {
try {
// Lógica da seção crítica aqui
executarTarefaProtegida();
} finally {
semáforoDistribuido.release(identificadorPermissao);
}
} else {
registrarFalhaAquisicao();
}
}
O método trySetPermits utiliza um script Lua no Redis para operações atômicas. A lógica pode ser representada como:
-- Verificação e definição atômica de permissões
local valorAtual = redis.call('get', KEYS[1])
if not valorAtual then
redis.call('set', KEYS[1], ARGV[1])
redis.call('publish', KEYS[2], ARGV[1])
return true
else
return false
end
Ao configurar o Redisson, selecione o modo correto do servidor. Um erro comum ocorre ao usar configuração de cluster indevidamente:
// Configuração incorreta para instância standalone
Config configErrada = new Config();
configErrada.useClusterServers()
.addNodeAddress("redis://localhost:6379"); // Isto causa exceção
// Configuração correta
Config configCorreta = new Config();
configCorreta.useSingleServer()
.setAddress("redis://localhost:6379");
Se trySetPermits retornar false repetidamente, verifique se a chave já existe no Redis, pois o método só define permissões se a chave for nova.