Skip to content

Commit 642d875

Browse files
fix:fix cache expiration but not remove circuit breaker. (#678)
Signed-off-by: Haotian Zhang <[email protected]>
1 parent 1e85ba5 commit 642d875

File tree

3 files changed

+99
-13
lines changed
  • polaris-circuitbreaker/polaris-circuitbreaker-factory/src/test/java/com/tencent/polaris/circuitbreaker/factory/test
  • polaris-plugins
    • polaris-plugins-circuitbreaker/circuitbreaker-composite/src/test/java/com/tencent/polaris/plugins/circuitbreaker/composite
    • polaris-plugins-registry/registry-memory/src/main/java/com/tencent/polaris/plugins/registry/memory

3 files changed

+99
-13
lines changed

polaris-circuitbreaker/polaris-circuitbreaker-factory/src/test/java/com/tencent/polaris/circuitbreaker/factory/test/CircuitBreakerTest.java

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,13 @@
1717

1818
package com.tencent.polaris.circuitbreaker.factory.test;
1919

20+
import com.google.common.cache.Cache;
2021
import com.google.protobuf.util.JsonFormat;
2122
import com.tencent.polaris.api.config.Configuration;
23+
import com.tencent.polaris.api.plugin.circuitbreaker.CircuitBreaker;
24+
import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat;
25+
import com.tencent.polaris.api.plugin.circuitbreaker.entity.Resource;
26+
import com.tencent.polaris.api.plugin.circuitbreaker.entity.ServiceResource;
2227
import com.tencent.polaris.api.pojo.Instance;
2328
import com.tencent.polaris.api.pojo.RetStatus;
2429
import com.tencent.polaris.api.pojo.ServiceKey;
@@ -29,16 +34,19 @@
2934
import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
3035
import com.tencent.polaris.circuitbreak.api.FunctionalDecorator;
3136
import com.tencent.polaris.circuitbreak.api.pojo.FunctionalDecoratorRequest;
37+
import com.tencent.polaris.circuitbreak.client.api.DefaultCircuitBreakAPI;
3238
import com.tencent.polaris.circuitbreak.client.exception.CallAbortedException;
3339
import com.tencent.polaris.circuitbreak.factory.CircuitBreakAPIFactory;
3440
import com.tencent.polaris.client.util.Utils;
41+
import com.tencent.polaris.factory.config.ConfigurationImpl;
3542
import com.tencent.polaris.logging.LoggerFactory;
43+
import com.tencent.polaris.plugins.circuitbreaker.composite.PolarisCircuitBreaker;
44+
import com.tencent.polaris.plugins.circuitbreaker.composite.ResourceCounters;
3645
import com.tencent.polaris.specification.api.v1.fault.tolerance.CircuitBreakerProto;
3746
import com.tencent.polaris.test.common.TestUtils;
3847
import com.tencent.polaris.test.mock.discovery.NamingServer;
3948
import com.tencent.polaris.test.mock.discovery.NamingService.InstanceParameter;
4049
import org.junit.After;
41-
import org.junit.Assert;
4250
import org.junit.Before;
4351
import org.junit.Test;
4452
import org.slf4j.Logger;
@@ -49,12 +57,18 @@
4957
import java.io.InputStreamReader;
5058
import java.nio.charset.StandardCharsets;
5159
import java.util.List;
60+
import java.util.Map;
61+
import java.util.Optional;
62+
import java.util.concurrent.TimeUnit;
5263
import java.util.function.Consumer;
5364
import java.util.stream.Collectors;
5465

5566
import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST;
5667
import static com.tencent.polaris.test.common.Consts.SERVICE_CIRCUIT_BREAKER;
5768
import static com.tencent.polaris.test.common.TestUtils.SERVER_ADDRESS_ENV;
69+
import static org.assertj.core.api.Assertions.assertThat;
70+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
71+
import static org.assertj.core.api.Assertions.fail;
5872

5973
/**
6074
* CircuitBreakerTest.java
@@ -76,7 +90,7 @@ public void before() throws IOException {
7690
namingServer = NamingServer.startNamingServer(-1);
7791
System.setProperty(SERVER_ADDRESS_ENV, String.format("127.0.0.1:%d", namingServer.getPort()));
7892
} catch (IOException e) {
79-
Assert.fail(e.getMessage());
93+
fail(e.getMessage());
8094
}
8195
ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, SERVICE_CIRCUIT_BREAKER);
8296
InstanceParameter parameter = new InstanceParameter();
@@ -124,7 +138,7 @@ public void testUpdateServiceCallResult() {
124138
req.setNamespace(NAMESPACE_TEST);
125139
req.setService(SERVICE_CIRCUIT_BREAKER);
126140
List<Instance> instances = assemblyAPI.getReachableInstances(req);
127-
Assert.assertEquals(MAX_COUNT, instances.size());
141+
assertThat(instances.size()).isEqualTo(MAX_COUNT);
128142
Instance instanceToLimit = instances.get(index);
129143
ServiceCallResult result = instanceToResult(instanceToLimit);
130144
result.setRetCode(-1);
@@ -158,8 +172,38 @@ public void testFunctionalDecorator() {
158172
throw e;
159173
}
160174
}
161-
Assert.assertThrows(CallAbortedException.class, () -> integerConsumer.accept(3));
175+
assertThatThrownBy(() -> integerConsumer.accept(3)).isInstanceOf(CallAbortedException.class);
162176
}
163177
}
164178

179+
@Test
180+
public void testCircuitBreakerRuleExpiration() throws InterruptedException {
181+
Configuration configuration = TestUtils.configWithEnvAddress();
182+
ConfigurationImpl configurationImpl = (ConfigurationImpl) configuration;
183+
configurationImpl.getConsumer().getLocalCache().setServiceExpireEnable(true);
184+
configurationImpl.getConsumer().getLocalCache().setServiceExpireTime(5000);
185+
configurationImpl.getConsumer().getCircuitBreaker().setDefaultRuleEnable(false);
186+
try (CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPIByConfig(configurationImpl)) {
187+
Utils.sleepUninterrupted(10000);
188+
ServiceKey serviceKey = new ServiceKey(NAMESPACE_TEST, SERVICE_CIRCUIT_BREAKER);
189+
Resource svcResource = new ServiceResource(serviceKey);
190+
ResourceStat resourceStat = new ResourceStat(svcResource, 500, 1000);
191+
circuitBreakAPI.report(resourceStat);
192+
193+
DefaultCircuitBreakAPI defaultCircuitBreakAPI = (DefaultCircuitBreakAPI) circuitBreakAPI;
194+
CircuitBreaker circuitBreaker = defaultCircuitBreakAPI.getSDKContext().getExtensions().getResourceBreaker();
195+
PolarisCircuitBreaker polarisCircuitBreaker = (PolarisCircuitBreaker) circuitBreaker;
196+
Map<CircuitBreakerProto.Level, Cache<Resource, Optional<ResourceCounters>>> countersCache = polarisCircuitBreaker.getCountersCache();
197+
Cache<Resource, Optional<ResourceCounters>> cacheValue = countersCache.get(CircuitBreakerProto.Level.SERVICE);
198+
assertThat(cacheValue.getIfPresent(svcResource)).isNotNull();
199+
200+
// 熔断规则过期清理熔断器
201+
TimeUnit.MILLISECONDS.sleep(10000);
202+
assertThat(cacheValue.getIfPresent(svcResource)).isNull();
203+
204+
// 重新创建熔断器
205+
polarisCircuitBreaker.report(resourceStat);
206+
assertThat(cacheValue.getIfPresent(svcResource)).isNotNull();
207+
}
208+
}
165209
}

polaris-plugins/polaris-plugins-circuitbreaker/circuitbreaker-composite/src/test/java/com/tencent/polaris/plugins/circuitbreaker/composite/PolarisCircuitBreakerTest.java

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,14 @@
4444
import com.tencent.polaris.specification.api.v1.model.ModelProto.MatchString.MatchStringType;
4545
import com.tencent.polaris.test.common.MockInitContext;
4646
import com.tencent.polaris.test.mock.discovery.MockServiceResourceProvider;
47-
import org.junit.Assert;
4847
import org.junit.Test;
4948

49+
import java.util.Map;
5050
import java.util.Optional;
5151
import java.util.regex.Pattern;
5252

53+
import static org.assertj.core.api.Assertions.assertThat;
54+
5355
public class PolarisCircuitBreakerTest {
5456

5557
public CircuitBreaker buildRules() {
@@ -114,9 +116,9 @@ public void testCheckResource() {
114116
}
115117
}
116118
CircuitBreakerStatus circuitBreakerStatus = polarisCircuitBreaker.checkResource(svcResource);
117-
Assert.assertNotNull(circuitBreakerStatus);
119+
assertThat(circuitBreakerStatus).isNotNull();
118120
Status status = circuitBreakerStatus.getStatus();
119-
Assert.assertEquals(Status.OPEN, status);
121+
assertThat(status).isEqualTo(Status.OPEN);
120122
}
121123

122124
@Test
@@ -168,7 +170,7 @@ public void testRuleChanged() {
168170
}
169171
CircuitBreakerStatus circuitBreakerStatus = polarisCircuitBreaker.checkResource(svcResource);
170172
Status status = circuitBreakerStatus.getStatus();
171-
Assert.assertEquals(Status.OPEN, status);
173+
assertThat(status).isEqualTo(Status.OPEN);
172174
}
173175

174176
@Test
@@ -238,10 +240,10 @@ public void testCircuitBreakerMethodRules() {
238240
for (int i = 0; i < 1000; i++) {
239241
Resource methodResource = new MethodResource(serviceKey, String.format("/d/customers/base/%d", i));
240242
CircuitBreakerStatus circuitBreakerStatus = polarisCircuitBreaker.checkResource(methodResource);
241-
Assert.assertEquals(Status.OPEN, circuitBreakerStatus.getStatus());
243+
assertThat(circuitBreakerStatus.getStatus()).isEqualTo(Status.OPEN);
242244
}
243-
Assert.assertEquals(1, polarisCircuitBreaker.getCountersCache().get(Level.METHOD).size());
244-
Assert.assertEquals(1000, polarisCircuitBreaker.getResourceMappingSize());
245+
assertThat(polarisCircuitBreaker.getCountersCache().get(Level.METHOD).size()).isEqualTo(1);
246+
assertThat(polarisCircuitBreaker.getResourceMappingSize()).isEqualTo(1000);
245247

246248
//check cleanup
247249
try {
@@ -250,6 +252,43 @@ public void testCircuitBreakerMethodRules() {
250252
e.printStackTrace();
251253
}
252254
polarisCircuitBreaker.cleanupExpiredResources();
253-
Assert.assertEquals(0, polarisCircuitBreaker.getResourceMappingSize());
255+
assertThat(polarisCircuitBreaker.getResourceMappingSize()).isEqualTo(0);
256+
}
257+
258+
@Test
259+
public void testCircuitBreakerRuleExpiration() throws InterruptedException {
260+
MockServiceResourceProvider mockServiceRuleProvider = new MockServiceResourceProvider();
261+
PolarisCircuitBreaker polarisCircuitBreaker = new PolarisCircuitBreaker();
262+
Configuration configuration = ConfigAPIFactory.defaultConfig();
263+
ConfigurationImpl configurationImpl = (ConfigurationImpl) configuration;
264+
configurationImpl.getConsumer().getCircuitBreaker().setDefaultRuleEnable(false);
265+
InitContext initContext = new MockInitContext(configuration);
266+
polarisCircuitBreaker.init(initContext);
267+
polarisCircuitBreaker.setServiceRuleProvider(mockServiceRuleProvider);
268+
polarisCircuitBreaker.setCircuitBreakerRuleDictionary(new CircuitBreakerRuleDictionary(Pattern::compile, null));
269+
polarisCircuitBreaker.setFaultDetectRuleDictionary(new FaultDetectRuleDictionary());
270+
ServiceKey serviceKey = new ServiceKey("Test", "testMethodSvc");
271+
ServiceEventKey serviceEventKey = new ServiceEventKey(serviceKey, EventType.CIRCUIT_BREAKING);
272+
CircuitBreaker circuitBreaker = buildRules();
273+
ServiceRuleByProto serviceRule = new ServiceRuleByProto(circuitBreaker, circuitBreaker.getRevision().getValue(),
274+
false,
275+
EventType.CIRCUIT_BREAKING);
276+
mockServiceRuleProvider.putServiceRule(serviceEventKey, serviceRule);
277+
278+
// 创建熔断器
279+
Resource svcResource = new ServiceResource(serviceKey);
280+
ResourceStat resourceStat = new ResourceStat(svcResource, 500, 1000);
281+
polarisCircuitBreaker.report(resourceStat);
282+
Map<Level, Cache<Resource, Optional<ResourceCounters>>> countersCache = polarisCircuitBreaker.getCountersCache();
283+
Cache<Resource, Optional<ResourceCounters>> cacheValue = countersCache.get(Level.SERVICE);
284+
assertThat(cacheValue.getIfPresent(svcResource)).isNotNull();
285+
286+
// 熔断规则过期清理熔断器
287+
polarisCircuitBreaker.onCircuitBreakerRuleChanged(serviceKey);
288+
assertThat(cacheValue.getIfPresent(svcResource)).isNull();
289+
290+
// 重新创建熔断器
291+
polarisCircuitBreaker.report(resourceStat);
292+
assertThat(cacheValue.getIfPresent(svcResource)).isNotNull();
254293
}
255294
}

polaris-plugins/polaris-plugins-registry/registry-memory/src/main/java/com/tencent/polaris/plugins/registry/memory/InMemoryRegistry.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,8 +644,11 @@ public void run() {
644644
if (diffTimeMs < InMemoryRegistry.this.serviceExpireTimeMs) {
645645
continue;
646646
}
647+
ServiceEventKey svcEventKey = entry.getKey();
647648
//执行淘汰
648-
removeCache(entry.getKey());
649+
removeCache(svcEventKey);
650+
resourceEventListeners.forEach(listener ->
651+
listener.onResourceDeleted(svcEventKey, cacheObject.getValue()));
649652
}
650653
}
651654
}

0 commit comments

Comments
 (0)