Skip to content

Commit 3fa61af

Browse files
authored
Creating an abstraction of circuit breaker implementation (#551)
* setup resilience4j * specifying circuit breaker strategy name * creating agnostic interface to support multiple circuit breaker strategy types * fixme * sppliting circuit breaker factory * refactoring is done * test is passing * test is passing * test is passing * refactoring package * [Gradle Release Plugin] - new version commit: '3.25.11-snapshot'. * release notes * [Gradle Release Plugin] - new version commit: '3.25.12-snapshot'. * release notes * fixme note * fixme note
1 parent c170592 commit 3fa61af

21 files changed

+405
-164
lines changed

RELEASE-NOTES.md

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 3.25.12
2+
* Creating an abstraction of circuit breaker implementation #533
3+
14
## 3.25.11
25
* Agnostic interface to support multiple circuit breaker strategies config #533
36

@@ -31,7 +34,7 @@
3134

3235
## 3.25.2
3336
* Migrating cache to caffeine #522
34-
37+
3538
## 3.25.1
3639
* Ensure thread will have name at the logs, behavior changed since `3.25.0` #436.
3740

@@ -54,11 +57,11 @@
5457
* Fixing graal-sdk dep binary impacts arm, windows, amd static generation
5558
* Fixed Jar release which was broken when at `3.22.0` depending on the JRE vendor
5659

57-
## 3.22.0
60+
## 3.22.0
5861
* #473: Qemu upgrade
5962

6063
## 3.21.3
61-
* #496: Fixing aarch binary not building
64+
* #496: Fixing aarch binary not building
6265

6366
## 3.21.2
6467
* #285, #494: Fixing amd64 static docker image.
@@ -115,15 +118,15 @@
115118
* Parameters for Remote Solver Circuit Breaker, see #440.
116119

117120
## 3.17.3
118-
* DPS Config module refactoring due #440, see #447
121+
* DPS Config module refactoring due #440, see #447
119122

120123
## 3.17.2
121124
* Fixing regression, leading with no ipv6 response, see #446
122125

123126
## 3.17.1
124-
* Docker Solver module refactoring, see #444
127+
* Docker Solver module refactoring, see #444
125128

126-
## 3.17.0
129+
## 3.17.0
127130
* Feature toggle to turn off Docker Solver Host Machine IP fallback, see #442
128131

129132
## 3.16.3
@@ -140,11 +143,11 @@
140143

141144
## 3.15
142145
* Support for AAAA records on Docker container, LocalDB and System solving.
143-
* AAAA GUI records support
146+
* AAAA GUI records support
144147
* DPS Network IPV6 Support
145148
* Formalize Recursion Available on query responses as DPS supports this feature already, see #392
146-
* Defined a new process of releasing the stable versions, see "Getting Started -> Release Version Control"
147-
for more details
149+
* Defined a new process of releasing the stable versions, see "Getting Started -> Release Version Control"
150+
for more details
148151
* Fixed arm64 images stopped being pushed at `3.9`
149152
* Cache improvement for a concurrent approach synchronized by key
150153
* Increasing tcp and udp server parallelism from 20 to 50 threads each, threads are created lazily
@@ -177,7 +180,7 @@ for more details
177180
* Gui interface to clear the cache
178181
* Created but not documented APIs to get cache size its and values
179182
* Increased remote solver timeout to 10 seconds to make sure won't get easlily get timeout due to server slowness
180-
* Ordering interfaces by index when choosing an IP as the machine IP, put loopback at the end of the list.
183+
* Ordering interfaces by index when choosing an IP as the machine IP, put loopback at the end of the list.
181184
* Holding TCP open connections up to 2min respecting RFC-1035 section "4.2.2. TCP usage"
182185
* Fixed too many occurrences of "java.net.SocketException: Socket closed"
183186
* Limited TCP/UDP Server thread pool up to 20 threads due to control memory usage
@@ -249,15 +252,15 @@ They will separate by comma , DPS will look for each value, try to use it and st
249252
* When finding network by name must find with the exact name
250253

251254
## 3.2.3-beta
252-
* Fixed docker container wasn't solving from env when the names weren't separated by ` , `
253-
(spaces before and after the comma were needed)
255+
* Fixed docker container wasn't solving from env when the names weren't separated by ` , `
256+
(spaces before and after the comma were needed)
254257

255258
## 3.2.2-beta
256-
* Fixed DPS container was connecting to DPS network with wrong IP
259+
* Fixed DPS container was connecting to DPS network with wrong IP
257260

258261
## 3.2.1-beta
259262
* Respecting OS to configure as default DNS
260-
* Other minor fixes
263+
* Other minor fixes
261264

262265
## 3.2.0-beta
263266
* Better error treating and log formatting
@@ -272,7 +275,7 @@ They will separate by comma , DPS will look for each value, try to use it and st
272275

273276
## 3.1.5-beta
274277
* Fixing UDP binding server to any interface on the machine wasn't working for some clients
275-
278+
276279
## 3.1.4-beta
277280
* Binding UDP server to any interface on the machine
278281
* Fallback to 127.0.0.1 interface when the real one is missing
@@ -307,7 +310,7 @@ DPS 3 - Minor fixes
307310

308311
## 3.0.1-beta
309312
* DPS has your code totally refactored by maintaining the previous features, it's a structuring for new features
310-
See details at [DNS Proxy Server 3 #267](https://github.com/mageddo/dns-proxy-server/issues/267)
313+
See details at [DNS Proxy Server 3 #267](https://github.com/mageddo/dns-proxy-server/issues/267)
311314

312315
## 2.19.0
313316
* Support for absolute paths on config files (#188)
@@ -339,9 +342,9 @@ DPS 3 - Minor fixes
339342
* Change log level before try to log something
340343

341344
## 2.18.0
342-
* Feature: Multiple environments, now you can setup a group of hostnames and save it to a environment, then you can
343-
create a new environment and switch between them, very useful when working on different contexts switching from QA to PROD,
344-
for example, [see the docs](http://mageddo.github.io/dns-proxy-server/2.18/en/2-features/multiple-environments/)
345+
* Feature: Multiple environments, now you can setup a group of hostnames and save it to a environment, then you can
346+
create a new environment and switch between them, very useful when working on different contexts switching from QA to PROD,
347+
for example, [see the docs](http://mageddo.github.io/dns-proxy-server/2.18/en/2-features/multiple-environments/)
345348

346349
## 2.17.4
347350
* Clearing cache for resolvers when the config file is saved
@@ -365,7 +368,7 @@ for example, [see the docs](http://mageddo.github.io/dns-proxy-server/2.18/en/2-
365368
## 2.15.0
366369
* Decreasing chance of acl issues by giving priority to answer ip of bridge networks over overlay ones
367370
* Now DPS can have your own network this way it can access and be accessed
368-
by all docker containers, **not** enabled by default [see the docs](http://mageddo.github.io/dns-proxy-server/2.15/en/2-features/dps-network-resolution/)
371+
by all docker containers, **not** enabled by default [see the docs](http://mageddo.github.io/dns-proxy-server/2.15/en/2-features/dps-network-resolution/)
369372

370373
## 2.14.6
371374
* Fixing ping slowness
@@ -374,13 +377,13 @@ by all docker containers, **not** enabled by default [see the docs](http://maged
374377
* Fixing docker hub push
375378

376379
## 2.14.4
377-
* Fixing log level wasn't being respected
380+
* Fixing log level wasn't being respected
378381

379382
## 2.14.2
380383
* Ability to specify remote server port
381384
* Introducing storage api v2
382-
* Refactoring the docs to use Hugo templates
383-
385+
* Refactoring the docs to use Hugo templates
386+
384387
## 2.14.1
385388
* Fixing nil pointer when remote server get timeout (#126)
386389
* Simplify bug report
@@ -393,7 +396,7 @@ by all docker containers, **not** enabled by default [see the docs](http://maged
393396
## 2.13.2
394397
* Fixing broken answer when hostname is not found
395398
* Fixing ping slowness
396-
399+
397400
## 2.13.1
398401
* Make sure value column will not break the table (#116)
399402

@@ -448,7 +451,7 @@ by all docker containers, **not** enabled by default [see the docs](http://maged
448451
* Fixing wildcard resolution were not solving main domain to docker container, just the subdomains
449452

450453
## 2.5.1
451-
* Fixing ping slowness, takes more than 10 seconds to respond
454+
* Fixing ping slowness, takes more than 10 seconds to respond
452455

453456
## 2.5.0
454457
* Migrate to static logging tool
@@ -462,7 +465,7 @@ by all docker containers, **not** enabled by default [see the docs](http://maged
462465

463466
## 2.3.3
464467
* Domains wildcard support
465-
If you register a hostname with `.` at start, then all subdomains will solve to that container/local storage entry
468+
If you register a hostname with `.` at start, then all subdomains will solve to that container/local storage entry
466469

467470
## 2.2.3
468471
* Some times container hostname don't get registered at machine startup
@@ -488,16 +491,16 @@ If you register a hostname with `.` at start, then all subdomains will solve to
488491
* Automating build with Travis
489492

490493
## 2.1.1
491-
* Fix - `Error response from daemon: No such container...` message. see #29
492-
* Fix - hostname don't get removed when the container has killed. see #26
494+
* Fix - `Error response from daemon: No such container...` message. see #29
495+
* Fix - hostname don't get removed when the container has killed. see #26
493496

494497
## 2.1.0
495498
* Turn publish port optional when running as service using docker mode
496499

497500
## 2.0.21
498501
* BugFix - Service stopped of work in normal mode
499502

500-
## 2.0.20
503+
## 2.0.20
501504
* Support for --version option that shows the current version
502505
* Docker Compose is not required anymore to run DNS Proxy Server as a docker service
503506

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version=3.25.11-snapshot
1+
version=3.25.12-snapshot
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.mageddo.commons.circuitbreaker;
2+
3+
public class CircuitIsOpenException extends RuntimeException {
4+
public CircuitIsOpenException(Throwable e) {
5+
super(e);
6+
}
7+
}

src/main/java/com/mageddo/dnsproxyserver/config/Config.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public void resetConfigFile() {
9090
}
9191

9292
@JsonIgnore
93-
public CircuitBreakerStrategy getSolverRemoteCircuitBreaker() {
93+
public CircuitBreakerStrategy getSolverRemoteCircuitBreakerStrategy() {
9494
if (this.solverRemote == null) {
9595
return null;
9696
}

src/main/java/com/mageddo/dnsproxyserver/config/mapper/ConfigMapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ private static Config mapFrom0(List<Config> configs) {
5151
.solverRemote(SolverRemote
5252
.builder()
5353
.active(firstNonNullRequiring(mapField(Config::isSolverRemoteActive, configs)))
54-
.circuitBreaker(firstNonNullRequiring(mapField(Config::getSolverRemoteCircuitBreaker, configs)))
54+
.circuitBreaker(firstNonNullRequiring(mapField(Config::getSolverRemoteCircuitBreakerStrategy, configs)))
5555
.build()
5656
)
5757
.build();

src/main/java/com/mageddo/dnsproxyserver/config/validator/ConfigValidator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@ public static void validate(Config config) {
2525
Validate.notNull(config.isSolverRemoteActive(), "Solver remote active");
2626

2727
// fixme #533 this could not work every time after new types be created, check it
28-
CircuitBreakerValidator.validate((StaticThresholdCircuitBreakerStrategy) config.getSolverRemoteCircuitBreaker());
28+
CircuitBreakerValidator.validate((StaticThresholdCircuitBreakerStrategy) config.getSolverRemoteCircuitBreakerStrategy());
2929
}
3030
}

src/main/java/com/mageddo/dnsproxyserver/solver/remote/application/CircuitBreakerNonResilientService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.net.InetSocketAddress;
77
import java.util.function.Supplier;
88

9+
// todo #533 criar um CircuitBreakerDelegate para esta classe
910
public class CircuitBreakerNonResilientService implements CircuitBreakerService {
1011
@Override
1112
public Result safeHandle(final InetSocketAddress resolverAddress, Supplier<Result> sup) {

src/main/java/com/mageddo/dnsproxyserver/solver/remote/application/CircuitBreakerService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
public interface CircuitBreakerService {
1010

11+
// fixme #533 esse padrão de strategy não é mais necessário aqui, foi movido para CircuitBreakerDelegate
12+
// onde tem mais chances de reduzir duplicação
1113
Result safeHandle(final InetSocketAddress resolverAddress, Supplier<Result> sup);
1214

1315
CircuitStatus findCircuitStatus(InetSocketAddress resolverAddress);
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.mageddo.dnsproxyserver.solver.remote.application;
2+
3+
import com.mageddo.commons.circuitbreaker.CircuitCheckException;
4+
import com.mageddo.dnsproxyserver.config.StaticThresholdCircuitBreakerStrategy;
5+
import com.mageddo.dnsproxyserver.solver.remote.CircuitStatus;
6+
import com.mageddo.dnsproxyserver.solver.remote.Result;
7+
import com.mageddo.dnsproxyserver.solver.remote.mapper.CircuitBreakerStateMapper;
8+
import dev.failsafe.CircuitBreaker;
9+
import dev.failsafe.event.CircuitBreakerStateChangedEvent;
10+
import dev.failsafe.event.EventListener;
11+
import lombok.RequiredArgsConstructor;
12+
import lombok.extern.slf4j.Slf4j;
13+
14+
import javax.inject.Inject;
15+
import javax.inject.Singleton;
16+
import java.net.InetSocketAddress;
17+
18+
@Slf4j
19+
@Singleton
20+
@RequiredArgsConstructor(onConstructor = @__({@Inject}))
21+
public class FailsafeCircuitBreakerFactory {
22+
23+
private final OnCacheMustBeFlushedEvent onCacheMustBeFlushedEvent;
24+
25+
public CircuitBreaker<Result> build(
26+
InetSocketAddress address, StaticThresholdCircuitBreakerStrategy config
27+
) {
28+
return CircuitBreaker.<Result>builder()
29+
.handle(CircuitCheckException.class)
30+
.withFailureThreshold(config.getFailureThreshold(), config.getFailureThresholdCapacity())
31+
.withSuccessThreshold(config.getSuccessThreshold())
32+
.withDelay(config.getTestDelay())
33+
.onClose(build(CircuitStatus.CLOSED, address))
34+
.onOpen(build(CircuitStatus.OPEN, address))
35+
.onHalfOpen(it -> log.trace("status=halfOpen, server={}", address))
36+
.build();
37+
}
38+
39+
private EventListener<CircuitBreakerStateChangedEvent> build(
40+
CircuitStatus actualStateName, InetSocketAddress address
41+
) {
42+
return event -> {
43+
final var previousStateName = CircuitBreakerStateMapper.toStateNameFrom(event);
44+
if (isHalfOpenToOpen(previousStateName, actualStateName)) {
45+
log.trace("status=ignoredTransition, from={}, to={}", previousStateName, actualStateName);
46+
return;
47+
}
48+
log.trace(
49+
"status=beforeFlushCaches, address={}, previous={}, actual={}", address, previousStateName, actualStateName
50+
);
51+
this.onCacheMustBeFlushedEvent.run();
52+
log.debug(
53+
"status=clearedCache, address={}, previous={}, actual={}", address, previousStateName, actualStateName
54+
);
55+
};
56+
}
57+
58+
59+
private static boolean isHalfOpenToOpen(CircuitStatus previousStateName, CircuitStatus actualStateName) {
60+
return CircuitStatus.HALF_OPEN.equals(previousStateName) && CircuitStatus.OPEN.equals(actualStateName);
61+
}
62+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.mageddo.dnsproxyserver.solver.remote.application;
2+
3+
import com.mageddo.dnsproxyserver.solver.remote.dataprovider.SolverConsistencyGuaranteeDAO;
4+
import lombok.RequiredArgsConstructor;
5+
import lombok.extern.slf4j.Slf4j;
6+
7+
import javax.inject.Inject;
8+
import javax.inject.Singleton;
9+
10+
@Slf4j
11+
@Singleton
12+
@RequiredArgsConstructor(onConstructor = @__({@Inject}))
13+
public class OnCacheMustBeFlushedEvent {
14+
15+
private final SolverConsistencyGuaranteeDAO solverConsistencyGuaranteeDAO;
16+
17+
public void run() {
18+
this.solverConsistencyGuaranteeDAO.flushCachesFromCircuitBreakerStateChange();
19+
log.debug("status=flushed");
20+
}
21+
}

0 commit comments

Comments
 (0)