Remove unused jedis library
This commit is contained in:
parent
7a5dcc700e
commit
b44599cd59
6
pom.xml
6
pom.xml
|
@ -49,7 +49,6 @@
|
||||||
<gson.version>2.9.0</gson.version>
|
<gson.version>2.9.0</gson.version>
|
||||||
<jackson.version>2.13.4</jackson.version>
|
<jackson.version>2.13.4</jackson.version>
|
||||||
<jaxb.version>2.3.1</jaxb.version>
|
<jaxb.version>2.3.1</jaxb.version>
|
||||||
<jedis.version>2.9.0</jedis.version>
|
|
||||||
<kotlin.version>1.8.0</kotlin.version>
|
<kotlin.version>1.8.0</kotlin.version>
|
||||||
<kotlinx-serialization.version>1.4.1</kotlinx-serialization.version>
|
<kotlinx-serialization.version>1.4.1</kotlinx-serialization.version>
|
||||||
<lettuce.version>6.2.4.RELEASE</lettuce.version>
|
<lettuce.version>6.2.4.RELEASE</lettuce.version>
|
||||||
|
@ -253,11 +252,6 @@
|
||||||
<version>${slf4j.version}</version>
|
<version>${slf4j.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>redis.clients</groupId>
|
|
||||||
<artifactId>jedis</artifactId>
|
|
||||||
<version>${jedis.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-logging</groupId>
|
<groupId>commons-logging</groupId>
|
||||||
<artifactId>commons-logging</artifactId>
|
<artifactId>commons-logging</artifactId>
|
||||||
|
|
|
@ -323,11 +323,6 @@
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>redis.clients</groupId>
|
|
||||||
<artifactId>jedis</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.lettuce</groupId>
|
<groupId>io.lettuce</groupId>
|
||||||
<artifactId>lettuce-core</artifactId>
|
<artifactId>lettuce-core</artifactId>
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2013-2020 Signal Messenger, LLC
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.whispersystems.textsecuregcm.redis;
|
|
||||||
|
|
||||||
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
|
|
||||||
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration;
|
|
||||||
import org.whispersystems.textsecuregcm.util.CircuitBreakerUtil;
|
|
||||||
import redis.clients.jedis.Jedis;
|
|
||||||
import redis.clients.jedis.JedisPool;
|
|
||||||
import redis.clients.jedis.exceptions.JedisException;
|
|
||||||
|
|
||||||
public class ReplicatedJedisPool {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(ReplicatedJedisPool.class);
|
|
||||||
private final AtomicInteger replicaIndex = new AtomicInteger(0);
|
|
||||||
|
|
||||||
private final Supplier<Jedis> master;
|
|
||||||
private final ArrayList<Supplier<Jedis>> replicas;
|
|
||||||
|
|
||||||
public ReplicatedJedisPool(String name,
|
|
||||||
JedisPool master,
|
|
||||||
List<JedisPool> replicas,
|
|
||||||
CircuitBreakerConfiguration circuitBreakerConfiguration)
|
|
||||||
{
|
|
||||||
if (replicas.size() < 1) throw new IllegalArgumentException("There must be at least one replica");
|
|
||||||
|
|
||||||
CircuitBreakerConfig config = circuitBreakerConfiguration.toCircuitBreakerConfig();
|
|
||||||
CircuitBreaker masterBreaker = CircuitBreaker.of(String.format("%s-master", name), config);
|
|
||||||
|
|
||||||
CircuitBreakerUtil.registerMetrics(masterBreaker, ReplicatedJedisPool.class);
|
|
||||||
|
|
||||||
this.master = CircuitBreaker.decorateSupplier(masterBreaker, master::getResource);
|
|
||||||
this.replicas = new ArrayList<>(replicas.size());
|
|
||||||
|
|
||||||
for (int i=0;i<replicas.size();i++) {
|
|
||||||
JedisPool replica = replicas.get(i);
|
|
||||||
CircuitBreaker slaveBreaker = CircuitBreaker.of(String.format("%s-slave-%d", name, i), config);
|
|
||||||
|
|
||||||
CircuitBreakerUtil.registerMetrics(slaveBreaker, ReplicatedJedisPool.class);
|
|
||||||
this.replicas.add(CircuitBreaker.decorateSupplier(slaveBreaker, replica::getResource));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Jedis getWriteResource() {
|
|
||||||
return master.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Jedis getReadResource() {
|
|
||||||
int failureCount = 0;
|
|
||||||
|
|
||||||
while (failureCount < replicas.size()) {
|
|
||||||
try {
|
|
||||||
return replicas.get(replicaIndex.getAndIncrement() % replicas.size()).get();
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
logger.error("Failure obtaining read replica pool", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
failureCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new JedisException("All read replica pools failed!");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,209 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2013 Signal Messenger, LLC
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.whispersystems.textsecuregcm.redis;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import io.github.resilience4j.circuitbreaker.CallNotPermittedException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration;
|
|
||||||
import redis.clients.jedis.Jedis;
|
|
||||||
import redis.clients.jedis.JedisPool;
|
|
||||||
import redis.clients.jedis.exceptions.JedisException;
|
|
||||||
|
|
||||||
class ReplicatedJedisPoolTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testWriteCheckoutNoSlaves() {
|
|
||||||
JedisPool master = mock(JedisPool.class);
|
|
||||||
|
|
||||||
try {
|
|
||||||
new ReplicatedJedisPool("testWriteCheckoutNoSlaves", master, new LinkedList<>(), new CircuitBreakerConfiguration());
|
|
||||||
throw new AssertionError();
|
|
||||||
} catch (Exception e) {
|
|
||||||
// good
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testWriteCheckoutWithSlaves() {
|
|
||||||
JedisPool master = mock(JedisPool.class);
|
|
||||||
JedisPool slave = mock(JedisPool.class);
|
|
||||||
Jedis instance = mock(Jedis.class );
|
|
||||||
|
|
||||||
when(master.getResource()).thenReturn(instance);
|
|
||||||
|
|
||||||
ReplicatedJedisPool replicatedJedisPool = new ReplicatedJedisPool("testWriteCheckoutWithSlaves", master, Collections.singletonList(slave), new CircuitBreakerConfiguration());
|
|
||||||
Jedis writeResource = replicatedJedisPool.getWriteResource();
|
|
||||||
|
|
||||||
assertThat(writeResource).isEqualTo(instance);
|
|
||||||
verify(master, times(1)).getResource();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testReadCheckouts() {
|
|
||||||
JedisPool master = mock(JedisPool.class);
|
|
||||||
JedisPool slaveOne = mock(JedisPool.class);
|
|
||||||
JedisPool slaveTwo = mock(JedisPool.class);
|
|
||||||
Jedis instanceOne = mock(Jedis.class );
|
|
||||||
Jedis instanceTwo = mock(Jedis.class );
|
|
||||||
|
|
||||||
when(slaveOne.getResource()).thenReturn(instanceOne);
|
|
||||||
when(slaveTwo.getResource()).thenReturn(instanceTwo);
|
|
||||||
|
|
||||||
ReplicatedJedisPool replicatedJedisPool = new ReplicatedJedisPool("testReadCheckouts", master, Arrays.asList(slaveOne, slaveTwo), new CircuitBreakerConfiguration());
|
|
||||||
|
|
||||||
assertThat(replicatedJedisPool.getReadResource()).isEqualTo(instanceOne);
|
|
||||||
assertThat(replicatedJedisPool.getReadResource()).isEqualTo(instanceTwo);
|
|
||||||
assertThat(replicatedJedisPool.getReadResource()).isEqualTo(instanceOne);
|
|
||||||
assertThat(replicatedJedisPool.getReadResource()).isEqualTo(instanceTwo);
|
|
||||||
assertThat(replicatedJedisPool.getReadResource()).isEqualTo(instanceOne);
|
|
||||||
|
|
||||||
verifyNoMoreInteractions(master);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testBrokenReadCheckout() {
|
|
||||||
JedisPool master = mock(JedisPool.class);
|
|
||||||
JedisPool slaveOne = mock(JedisPool.class);
|
|
||||||
JedisPool slaveTwo = mock(JedisPool.class);
|
|
||||||
Jedis instanceTwo = mock(Jedis.class );
|
|
||||||
|
|
||||||
when(slaveOne.getResource()).thenThrow(new JedisException("Connection failed!"));
|
|
||||||
when(slaveTwo.getResource()).thenReturn(instanceTwo);
|
|
||||||
|
|
||||||
ReplicatedJedisPool replicatedJedisPool = new ReplicatedJedisPool("testBrokenReadCheckout", master, Arrays.asList(slaveOne, slaveTwo), new CircuitBreakerConfiguration());
|
|
||||||
|
|
||||||
assertThat(replicatedJedisPool.getReadResource()).isEqualTo(instanceTwo);
|
|
||||||
assertThat(replicatedJedisPool.getReadResource()).isEqualTo(instanceTwo);
|
|
||||||
assertThat(replicatedJedisPool.getReadResource()).isEqualTo(instanceTwo);
|
|
||||||
|
|
||||||
verifyNoMoreInteractions(master);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testAllBrokenReadCheckout() {
|
|
||||||
JedisPool master = mock(JedisPool.class);
|
|
||||||
JedisPool slaveOne = mock(JedisPool.class);
|
|
||||||
JedisPool slaveTwo = mock(JedisPool.class);
|
|
||||||
|
|
||||||
when(slaveOne.getResource()).thenThrow(new JedisException("Connection failed!"));
|
|
||||||
when(slaveTwo.getResource()).thenThrow(new JedisException("Also failed!"));
|
|
||||||
|
|
||||||
ReplicatedJedisPool replicatedJedisPool = new ReplicatedJedisPool("testAllBrokenReadCheckout", master, Arrays.asList(slaveOne, slaveTwo), new CircuitBreakerConfiguration());
|
|
||||||
|
|
||||||
try {
|
|
||||||
replicatedJedisPool.getReadResource();
|
|
||||||
throw new AssertionError();
|
|
||||||
} catch (Exception e) {
|
|
||||||
// good
|
|
||||||
}
|
|
||||||
|
|
||||||
verifyNoMoreInteractions(master);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCircuitBreakerOpen() {
|
|
||||||
CircuitBreakerConfiguration configuration = new CircuitBreakerConfiguration();
|
|
||||||
configuration.setFailureRateThreshold(50);
|
|
||||||
configuration.setSlidingWindowSize(2);
|
|
||||||
configuration.setSlidingWindowMinimumNumberOfCalls(2);
|
|
||||||
|
|
||||||
JedisPool master = mock(JedisPool.class);
|
|
||||||
JedisPool slaveOne = mock(JedisPool.class);
|
|
||||||
JedisPool slaveTwo = mock(JedisPool.class);
|
|
||||||
|
|
||||||
when(master.getResource()).thenReturn(null);
|
|
||||||
when(slaveOne.getResource()).thenThrow(new JedisException("Connection failed!"));
|
|
||||||
when(slaveTwo.getResource()).thenThrow(new JedisException("Also failed!"));
|
|
||||||
|
|
||||||
ReplicatedJedisPool replicatedJedisPool = new ReplicatedJedisPool("testCircuitBreakerOpen", master,
|
|
||||||
Arrays.asList(slaveOne, slaveTwo), configuration);
|
|
||||||
replicatedJedisPool.getWriteResource();
|
|
||||||
|
|
||||||
when(master.getResource()).thenThrow(new JedisException("Master broken!"));
|
|
||||||
|
|
||||||
try {
|
|
||||||
replicatedJedisPool.getWriteResource();
|
|
||||||
throw new AssertionError();
|
|
||||||
} catch (JedisException exception) {
|
|
||||||
// good
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
replicatedJedisPool.getWriteResource();
|
|
||||||
throw new AssertionError();
|
|
||||||
} catch (CallNotPermittedException e) {
|
|
||||||
// good
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCircuitBreakerHalfOpen() throws InterruptedException {
|
|
||||||
CircuitBreakerConfiguration configuration = new CircuitBreakerConfiguration();
|
|
||||||
configuration.setFailureRateThreshold(50);
|
|
||||||
configuration.setSlidingWindowSize(2);
|
|
||||||
configuration.setSlidingWindowMinimumNumberOfCalls(2);
|
|
||||||
configuration.setPermittedNumberOfCallsInHalfOpenState(1);
|
|
||||||
configuration.setWaitDurationInOpenStateInSeconds(1);
|
|
||||||
|
|
||||||
JedisPool master = mock(JedisPool.class);
|
|
||||||
JedisPool slaveOne = mock(JedisPool.class);
|
|
||||||
JedisPool slaveTwo = mock(JedisPool.class);
|
|
||||||
|
|
||||||
when(master.getResource()).thenThrow(new JedisException("Master broken!"));
|
|
||||||
when(slaveOne.getResource()).thenThrow(new JedisException("Connection failed!"));
|
|
||||||
when(slaveTwo.getResource()).thenThrow(new JedisException("Also failed!"));
|
|
||||||
|
|
||||||
ReplicatedJedisPool replicatedJedisPool = new ReplicatedJedisPool("testCircuitBreakerHalfOpen", master, Arrays.asList(slaveOne, slaveTwo), configuration);
|
|
||||||
|
|
||||||
try {
|
|
||||||
replicatedJedisPool.getWriteResource();
|
|
||||||
throw new AssertionError();
|
|
||||||
} catch (JedisException exception) {
|
|
||||||
// good
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
replicatedJedisPool.getWriteResource();
|
|
||||||
throw new AssertionError();
|
|
||||||
} catch (JedisException exception) {
|
|
||||||
// good
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
replicatedJedisPool.getWriteResource();
|
|
||||||
throw new AssertionError();
|
|
||||||
} catch (CallNotPermittedException e) {
|
|
||||||
// good
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread.sleep(1100);
|
|
||||||
|
|
||||||
try {
|
|
||||||
replicatedJedisPool.getWriteResource();
|
|
||||||
throw new AssertionError();
|
|
||||||
} catch (JedisException exception) {
|
|
||||||
// good
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
replicatedJedisPool.getWriteResource();
|
|
||||||
throw new AssertionError();
|
|
||||||
} catch (CallNotPermittedException e) {
|
|
||||||
// good
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue