Skip to content

Commit fdb1a1d

Browse files
authored
SolverRemote: Exclude remote servers with open circuits. #526 (#531)
* release notes * removing old behavior test and activating the new one * refactoring and testing * refactoring tests * refactoring * [Gradle Release Plugin] - new version commit: '3.25.7-snapshot'. * disabling feature * release notes
1 parent 39c7bc7 commit fdb1a1d

File tree

11 files changed

+199
-160
lines changed

11 files changed

+199
-160
lines changed

RELEASE-NOTES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 3.25.7
2+
* Refactoring SolverRemote module to implement circuit optimization #526
3+
14
## 3.25.6
25
* Refactoring SolverRemote module to implement circuit optimization #526
36

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version=3.25.6-snapshot
1+
version=3.25.7-snapshot
Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,28 @@
11
package com.mageddo.dnsproxyserver.solver;
22

33
import com.mageddo.net.IpAddr;
4-
import com.mageddo.utils.Executors;
54

65
import java.util.List;
7-
import java.util.concurrent.Executor;
8-
import java.util.concurrent.ExecutorService;
96
import java.util.function.Function;
107

11-
public class RemoteResolvers implements AutoCloseable {
8+
public class RemoteResolvers {
129

1310
private final List<Resolver> resolvers;
14-
private final ExecutorService executor;
1511

16-
private RemoteResolvers(List<Resolver> resolvers, ExecutorService executor) {
12+
private RemoteResolvers(List<Resolver> resolvers) {
1713
this.resolvers = resolvers;
18-
this.executor = executor;
1914
}
2015

2116
public static RemoteResolvers of(List<IpAddr> servers, final Function<IpAddr, Resolver> resolverProvider) {
2217
final var resolvers = servers
2318
.stream()
2419
.map(resolverProvider)
2520
.toList();
26-
return new RemoteResolvers(resolvers, Executors.newThreadExecutor());
21+
return new RemoteResolvers(resolvers);
2722
}
2823

2924
public List<Resolver> resolvers() {
3025
return this.resolvers;
3126
}
3227

33-
@Override
34-
public void close() throws Exception {
35-
this.executor.close();
36-
}
37-
38-
public Executor getExecutor() {
39-
return this.executor;
40-
}
4128
}

src/main/java/com/mageddo/dnsproxyserver/solver/SolverRemote.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
import com.mageddo.commons.circuitbreaker.CircuitCheckException;
44
import com.mageddo.dns.utils.Messages;
5-
import com.mageddo.dnsproxyserver.solver.remote.application.CircuitBreakerService;
65
import com.mageddo.dnsproxyserver.solver.remote.Request;
76
import com.mageddo.dnsproxyserver.solver.remote.Result;
7+
import com.mageddo.dnsproxyserver.solver.remote.application.CircuitBreakerService;
8+
import com.mageddo.dnsproxyserver.solver.remote.application.ResolverStatsFactory;
89
import com.mageddo.net.NetExecutorWatchdog;
10+
import com.mageddo.utils.Executors;
911
import lombok.RequiredArgsConstructor;
1012
import lombok.extern.slf4j.Slf4j;
1113
import org.apache.commons.lang3.ClassUtils;
@@ -20,6 +22,7 @@
2022
import java.util.Objects;
2123
import java.util.concurrent.CompletableFuture;
2224
import java.util.concurrent.ExecutionException;
25+
import java.util.concurrent.ExecutorService;
2326
import java.util.concurrent.atomic.AtomicReference;
2427
import java.util.stream.Stream;
2528

@@ -33,9 +36,10 @@ public class SolverRemote implements Solver, AutoCloseable {
3336
static final String QUERY_TIMED_OUT_MSG = "Query timed out";
3437
public static final int PING_TIMEOUT_IN_MS = 1_500;
3538

36-
private final RemoteResolvers delegate;
37-
private final NetExecutorWatchdog netWatchdog = new NetExecutorWatchdog();
3839
private final CircuitBreakerService circuitBreakerService;
40+
private final ResolverStatsFactory resolverStatsFactory;
41+
private final NetExecutorWatchdog netWatchdog = new NetExecutorWatchdog();
42+
private final ExecutorService executor = Executors.newThreadExecutor();
3943

4044
@Override
4145
public Response handle(Message query) {
@@ -54,8 +58,7 @@ public Response handle(Message query) {
5458

5559
Result queryResultFromAvailableResolvers(Message query, StopWatch stopWatch) {
5660
final var lastErrorMsg = new AtomicReference<Message>();
57-
// fixme #526 better to exclude open circuits.
58-
final var resolvers = this.findResolversWithNonOpenCircuit();
61+
final var resolvers = this.findResolversToUse();
5962
for (int i = 0; i < resolvers.size(); i++) {
6063

6164
final var resolver = resolvers.get(i);
@@ -73,8 +76,8 @@ Result queryResultFromAvailableResolvers(Message query, StopWatch stopWatch) {
7376
return Result.fromErrorMessage(lastErrorMsg.get());
7477
}
7578

76-
List<Resolver> findResolversWithNonOpenCircuit() {
77-
return this.delegate.resolvers();
79+
List<Resolver> findResolversToUse() {
80+
return this.resolverStatsFactory.findResolversWithNonOpenCircuit();
7881
}
7982

8083
Request buildRequest(Message query, int resolverIndex, StopWatch stopWatch, Resolver resolver) {
@@ -93,13 +96,17 @@ Result safeQueryResult(Request req) {
9396
}
9497

9598
Result queryResult(Request req) {
96-
final var resFuture = req.sendQueryAsyncToResolver(this.delegate.getExecutor());
99+
final var resFuture = this.sendQueryAsyncToResolver(req);
97100
if (this.isPingWhileGettingQueryResponseActive()) {
98101
this.pingWhileGettingQueryResponse(req, resFuture);
99102
}
100103
return this.transformToResult(resFuture, req);
101104
}
102105

106+
CompletableFuture<Message> sendQueryAsyncToResolver(Request req) {
107+
return req.sendQueryAsyncToResolver(this.executor);
108+
}
109+
103110
void pingWhileGettingQueryResponse(Request req, CompletableFuture<Message> resFuture) {
104111
this.netWatchdog.watch(req.getResolverAddr(), resFuture, PING_TIMEOUT_IN_MS);
105112
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.mageddo.dnsproxyserver.solver.remote;
2+
3+
import com.mageddo.dnsproxyserver.solver.Resolver;
4+
import lombok.Builder;
5+
import lombok.Value;
6+
7+
@Value
8+
@Builder
9+
public class ResolverStats {
10+
11+
private Resolver resolver;
12+
private CircuitStatus circuitStatus;
13+
14+
public boolean isValidToUse() {
15+
return !CircuitStatus.OPEN.equals(this.circuitStatus);
16+
}
17+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.mageddo.dnsproxyserver.solver.remote.application;
2+
3+
import com.mageddo.dnsproxyserver.solver.RemoteResolvers;
4+
import com.mageddo.dnsproxyserver.solver.Resolver;
5+
import com.mageddo.dnsproxyserver.solver.remote.ResolverStats;
6+
import com.mageddo.dnsproxyserver.solver.remote.mapper.ResolverMapper;
7+
import lombok.RequiredArgsConstructor;
8+
9+
import javax.inject.Inject;
10+
import javax.inject.Singleton;
11+
import java.util.List;
12+
13+
@Singleton
14+
@RequiredArgsConstructor(onConstructor = @__({@Inject}))
15+
public class ResolverStatsFactory {
16+
17+
private final CircuitBreakerService circuitBreakerService;
18+
private final RemoteResolvers remoteResolvers;
19+
20+
public List<ResolverStats> find() {
21+
return this.remoteResolvers.resolvers()
22+
.stream()
23+
.map(this::find)
24+
.toList();
25+
}
26+
27+
public List<Resolver> findResolversWithNonOpenCircuit() {
28+
return this.find()
29+
.stream()
30+
.map(ResolverStats::getResolver)
31+
.toList()
32+
;
33+
}
34+
35+
public ResolverStats find(Resolver resolver) {
36+
return ResolverMapper.toResolverStats(resolver, this.circuitBreakerService.getCircuitStatus(resolver.getAddress()));
37+
}
38+
}

src/main/java/com/mageddo/dnsproxyserver/solver/remote/mapper/ResolverMapper.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33
import com.mageddo.dnsproxyserver.solver.Resolver;
44
import com.mageddo.dnsproxyserver.solver.SimpleResolver;
5+
import com.mageddo.dnsproxyserver.solver.remote.CircuitStatus;
6+
import com.mageddo.dnsproxyserver.solver.remote.ResolverStats;
57
import com.mageddo.dnsproxyserver.utils.InetAddresses;
68
import com.mageddo.net.IpAddr;
9+
import org.apache.commons.compress.harmony.unpack200.bytecode.BCIRenumberedAttribute;
710

811
import java.net.InetSocketAddress;
912
import java.time.Duration;
@@ -21,4 +24,13 @@ public static Resolver from(InetSocketAddress addr) {
2124
resolver.setTimeout(DEFAULT_TIMEOUT);
2225
return resolver;
2326
}
27+
28+
public static ResolverStats toResolverStats(Resolver resolver, CircuitStatus status) {
29+
return ResolverStats
30+
.builder()
31+
.resolver(resolver)
32+
.circuitStatus(status)
33+
.build()
34+
;
35+
}
2436
}

0 commit comments

Comments
 (0)