Skip to content

Commit 22498a7

Browse files
committed
Enhanced cluster-wrapper
1 parent 212808f commit 22498a7

File tree

2 files changed

+50
-53
lines changed

2 files changed

+50
-53
lines changed

cluster/src/main/java/io/scalecube/cluster/TransportWrapper.java

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
import java.util.Map;
88
import java.util.concurrent.ConcurrentHashMap;
99
import java.util.concurrent.atomic.AtomicInteger;
10+
import java.util.function.BiFunction;
1011
import reactor.core.publisher.Mono;
1112

1213
public class TransportWrapper {
1314

1415
private final Transport transport;
1516

16-
private final Map<Member, AtomicInteger> addressIndexByMember = new ConcurrentHashMap<>();
17+
private final Map<Member, Integer> addressIndexByMember = new ConcurrentHashMap<>();
1718

1819
public TransportWrapper(Transport transport) {
1920
this.transport = transport;
@@ -27,21 +28,7 @@ public TransportWrapper(Transport transport) {
2728
* @return mono result
2829
*/
2930
public Mono<Message> requestResponse(Member member, Message request) {
30-
final List<Address> addresses = member.addresses();
31-
final AtomicInteger currentIndex =
32-
addressIndexByMember.computeIfAbsent(member, m -> new AtomicInteger());
33-
return Mono.defer(
34-
() -> {
35-
synchronized (this) {
36-
if (currentIndex.get() == addresses.size()) {
37-
currentIndex.set(0);
38-
}
39-
final Address address = addresses.get(currentIndex.getAndIncrement());
40-
return transport.requestResponse(address, request);
41-
}
42-
})
43-
.retry(addresses.size() - 1)
44-
.doOnError(throwable -> addressIndexByMember.remove(member, currentIndex));
31+
return invokeWithRetry(member, request, transport::requestResponse);
4532
}
4633

4734
/**
@@ -52,20 +39,28 @@ public Mono<Message> requestResponse(Member member, Message request) {
5239
* @return mono result
5340
*/
5441
public Mono<Void> send(Member member, Message request) {
55-
final List<Address> addresses = member.addresses();
56-
final AtomicInteger currentIndex =
57-
addressIndexByMember.computeIfAbsent(member, m -> new AtomicInteger());
42+
return invokeWithRetry(member, request, transport::send);
43+
}
44+
45+
private <T> Mono<T> invokeWithRetry(
46+
Member member, Message request, BiFunction<Address, Message, Mono<T>> function) {
5847
return Mono.defer(
59-
() -> {
60-
synchronized (this) {
61-
if (currentIndex.get() == addresses.size()) {
62-
currentIndex.set(0);
63-
}
64-
final Address address = addresses.get(currentIndex.getAndIncrement());
65-
return transport.send(address, request);
66-
}
67-
})
68-
.retry(addresses.size() - 1)
69-
.doOnError(throwable -> addressIndexByMember.remove(member, currentIndex));
48+
() -> {
49+
final List<Address> addresses = member.addresses();
50+
final Integer index = addressIndexByMember.computeIfAbsent(member, m -> 0);
51+
final AtomicInteger currentIndex = new AtomicInteger(index);
52+
53+
return Mono.defer(
54+
() -> {
55+
if (currentIndex.get() == addresses.size()) {
56+
currentIndex.set(0);
57+
}
58+
final Address address = addresses.get(currentIndex.get());
59+
return function.apply(address, request);
60+
})
61+
.doOnSuccess(s -> addressIndexByMember.put(member, currentIndex.get()))
62+
.doOnError(ex -> currentIndex.incrementAndGet())
63+
.retry(addresses.size() - 1);
64+
});
7065
}
7166
}

cluster/src/test/java/io/scalecube/cluster/TransportWrapperTest.java

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package io.scalecube.cluster;
22

3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertSame;
35
import static org.mockito.Mockito.mock;
46
import static org.mockito.Mockito.when;
57

@@ -11,10 +13,8 @@
1113
import java.util.Collections;
1214
import java.util.List;
1315
import java.util.Map;
14-
import java.util.concurrent.atomic.AtomicInteger;
1516
import java.util.stream.Stream;
1617
import java.util.stream.Stream.Builder;
17-
import org.junit.jupiter.api.Assertions;
1818
import org.junit.jupiter.api.Test;
1919
import org.junit.jupiter.params.ParameterizedTest;
2020
import org.junit.jupiter.params.provider.Arguments;
@@ -76,12 +76,12 @@ static void populateBuilder(Builder<Arguments> builder, int size) {
7676
}
7777
}
7878

79-
private Map<Member, AtomicInteger> addressIndexByMember()
79+
private Map<Member, Integer> addressIndexByMember()
8080
throws NoSuchFieldException, IllegalAccessException {
8181
final Field field = TransportWrapper.class.getDeclaredField("addressIndexByMember");
8282
field.setAccessible(true);
8383
//noinspection unchecked
84-
return (Map<Member, AtomicInteger>) field.get(transportWrapper);
84+
return (Map<Member, Integer>) field.get(transportWrapper);
8585
}
8686

8787
@ParameterizedTest
@@ -95,7 +95,7 @@ void requestResponseShouldWorkByRoundRobin(int size, int startIndex, int success
9595
}
9696

9797
if (startIndex > 0) {
98-
addressIndexByMember().put(member, new AtomicInteger(startIndex));
98+
addressIndexByMember().put(member, startIndex);
9999
}
100100

101101
for (int i = 0; i < size; i++) {
@@ -109,9 +109,11 @@ void requestResponseShouldWorkByRoundRobin(int size, int startIndex, int success
109109
}
110110

111111
StepVerifier.create(transportWrapper.requestResponse(member, request))
112-
.assertNext(message -> Assertions.assertSame(response, message, "response"))
112+
.assertNext(message -> assertSame(response, message, "response"))
113113
.thenCancel()
114114
.verify();
115+
116+
assertEquals(successIndex, addressIndexByMember().get(member), "successIndex");
115117
}
116118

117119
@Test
@@ -124,13 +126,12 @@ void requestResponseShouldWorkThenFail() {
124126
.thenReturn(Mono.error(new RuntimeException("Error")));
125127

126128
StepVerifier.create(transportWrapper.requestResponse(member, request))
127-
.assertNext(message -> Assertions.assertSame(response, message, "response"))
129+
.assertNext(message -> assertSame(response, message, "response"))
128130
.thenCancel()
129131
.verify();
130132

131133
StepVerifier.create(transportWrapper.requestResponse(member, request))
132-
.verifyErrorSatisfies(
133-
throwable -> Assertions.assertEquals("Error", throwable.getMessage()));
134+
.verifyErrorSatisfies(throwable -> assertEquals("Error", throwable.getMessage()));
134135
}
135136

136137
@Test
@@ -143,11 +144,10 @@ void requestResponseShouldFailThenWork() {
143144
.thenReturn(Mono.just(response));
144145

145146
StepVerifier.create(transportWrapper.requestResponse(member, request))
146-
.verifyErrorSatisfies(
147-
throwable -> Assertions.assertEquals("Error", throwable.getMessage()));
147+
.verifyErrorSatisfies(throwable -> assertEquals("Error", throwable.getMessage()));
148148

149149
StepVerifier.create(transportWrapper.requestResponse(member, request))
150-
.assertNext(message -> Assertions.assertSame(response, message, "response"))
150+
.assertNext(message -> assertSame(response, message, "response"))
151151
.thenCancel()
152152
.verify();
153153
}
@@ -163,7 +163,7 @@ void requestResponseShouldFailByRoundRobin(int size, int startIndex, int ignore)
163163
}
164164

165165
if (startIndex > 0) {
166-
addressIndexByMember().put(member, new AtomicInteger(startIndex));
166+
addressIndexByMember().put(member, startIndex);
167167
}
168168

169169
for (int i = 0; i < size; i++) {
@@ -173,8 +173,9 @@ void requestResponseShouldFailByRoundRobin(int size, int startIndex, int ignore)
173173
}
174174

175175
StepVerifier.create(transportWrapper.requestResponse(member, request))
176-
.verifyErrorSatisfies(
177-
throwable -> Assertions.assertEquals("Error", throwable.getMessage()));
176+
.verifyErrorSatisfies(throwable -> assertEquals("Error", throwable.getMessage()));
177+
178+
assertEquals(startIndex, addressIndexByMember().get(member), "startIndex");
178179
}
179180

180181
@ParameterizedTest
@@ -187,7 +188,7 @@ void sendShouldWorkByRoundRobin(int size, int startIndex, int successIndex) thro
187188
}
188189

189190
if (startIndex > 0) {
190-
addressIndexByMember().put(member, new AtomicInteger(startIndex));
191+
addressIndexByMember().put(member, startIndex);
191192
}
192193

193194
for (int i = 0; i < size; i++) {
@@ -201,6 +202,8 @@ void sendShouldWorkByRoundRobin(int size, int startIndex, int successIndex) thro
201202
}
202203

203204
StepVerifier.create(transportWrapper.send(member, request)).verifyComplete();
205+
206+
assertEquals(successIndex, addressIndexByMember().get(member), "successIndex");
204207
}
205208

206209
@ParameterizedTest
@@ -213,7 +216,7 @@ void sendShouldFailByRoundRobin(int size, int startIndex, int ignore) throws Exc
213216
}
214217

215218
if (startIndex > 0) {
216-
addressIndexByMember().put(member, new AtomicInteger(startIndex));
219+
addressIndexByMember().put(member, startIndex);
217220
}
218221

219222
for (int i = 0; i < size; i++) {
@@ -222,8 +225,9 @@ void sendShouldFailByRoundRobin(int size, int startIndex, int ignore) throws Exc
222225
}
223226

224227
StepVerifier.create(transportWrapper.send(member, request))
225-
.verifyErrorSatisfies(
226-
throwable -> Assertions.assertEquals("Error", throwable.getMessage()));
228+
.verifyErrorSatisfies(throwable -> assertEquals("Error", throwable.getMessage()));
229+
230+
assertEquals(startIndex, addressIndexByMember().get(member), "startIndex");
227231
}
228232

229233
@Test
@@ -237,8 +241,7 @@ void sendShouldWorkThenFail() {
237241

238242
StepVerifier.create(transportWrapper.send(member, request)).verifyComplete();
239243
StepVerifier.create(transportWrapper.send(member, request))
240-
.verifyErrorSatisfies(
241-
throwable -> Assertions.assertEquals("Error", throwable.getMessage()));
244+
.verifyErrorSatisfies(throwable -> assertEquals("Error", throwable.getMessage()));
242245
}
243246

244247
@Test
@@ -251,8 +254,7 @@ void sendShouldFailThenWork() {
251254
.thenReturn(Mono.empty());
252255

253256
StepVerifier.create(transportWrapper.send(member, request))
254-
.verifyErrorSatisfies(
255-
throwable -> Assertions.assertEquals("Error", throwable.getMessage()));
257+
.verifyErrorSatisfies(throwable -> assertEquals("Error", throwable.getMessage()));
256258
StepVerifier.create(transportWrapper.send(member, request)).verifyComplete();
257259
}
258260
}

0 commit comments

Comments
 (0)