Skip to content

Commit 5235028

Browse files
committed
Propagate client thumbstone when a client creation fails
Closes: #30
1 parent 08e37a2 commit 5235028

File tree

2 files changed

+52
-9
lines changed

2 files changed

+52
-9
lines changed

src/main/java/org/tarantool/TarantoolClientImpl.java

+3-7
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@
2828

2929
public class TarantoolClientImpl extends TarantoolBase<Future<?>> implements TarantoolClient {
3030

31-
public static final CommunicationException NOT_INIT_EXCEPTION
32-
= new CommunicationException("Not connected, initializing connection");
33-
3431
protected TarantoolClientConfig config;
3532
protected long operationTimeout;
3633

@@ -101,7 +98,6 @@ public TarantoolClientImpl(SocketChannelProvider socketProvider, TarantoolClient
10198
}
10299

103100
private void initClient(SocketChannelProvider socketProvider, TarantoolClientConfig config) {
104-
this.thumbstone = NOT_INIT_EXCEPTION;
105101
this.config = config;
106102
this.initialRequestSize = config.defaultRequestSize;
107103
this.operationTimeout = config.operationExpiryTimeMillis;
@@ -130,8 +126,8 @@ private void startConnector(long initTimeoutMillis) {
130126
CommunicationException e = new CommunicationException(
131127
initTimeoutMillis +
132128
"ms is exceeded when waiting for client initialization. " +
133-
"You could configure init timeout in TarantoolConfig"
134-
);
129+
"You could configure init timeout in TarantoolConfig",
130+
thumbstone);
135131

136132
close(e);
137133
throw e;
@@ -147,7 +143,7 @@ protected void reconnect(Throwable lastError) {
147143
int retryNumber = 0;
148144
while (!Thread.currentThread().isInterrupted()) {
149145
try {
150-
channel = socketProvider.get(retryNumber++, lastError == NOT_INIT_EXCEPTION ? null : lastError);
146+
channel = socketProvider.get(retryNumber++, lastError);
151147
} catch (Exception e) {
152148
closeChannel(channel);
153149
lastError = e;

src/test/java/org/tarantool/ClientReconnectIT.java

+49-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.concurrent.TimeUnit;
2828
import java.util.concurrent.atomic.AtomicBoolean;
2929
import java.util.concurrent.atomic.AtomicInteger;
30+
import java.util.concurrent.atomic.AtomicReference;
3031
import java.util.concurrent.atomic.AtomicReferenceArray;
3132
import java.util.concurrent.locks.LockSupport;
3233

@@ -412,13 +413,59 @@ public void testReconnectWrongAuth() throws Exception {
412413
client.close();
413414
}
414415

415-
private TestSocketChannelProvider makeZeroLingerProvider() {
416+
@Test
417+
void testFirstConnectionRefused() {
418+
String errorText = "Fake error";
419+
RuntimeException error = new RuntimeException(errorText);
420+
TarantoolClientConfig config = makeDefaultClientConfig();
421+
config.initTimeoutMillis = 100;
422+
CommunicationException exception = assertThrows(
423+
CommunicationException.class,
424+
() -> new TarantoolClientImpl(makeErroredProvider(error), config)
425+
);
426+
Throwable wrapped = exception.getCause();
427+
Throwable origin = wrapped.getCause();
428+
assertEquals(errorText, wrapped.getMessage());
429+
assertEquals(error, origin);
430+
}
431+
432+
@Test
433+
void testConnectionRefusedAfterConnect() {
434+
TarantoolClientImpl client = new TarantoolClientImpl(makeErroredProvider(null), makeDefaultClientConfig());
435+
client.ping();
436+
437+
testHelper.stopInstance();
438+
CommunicationException exception = assertThrows(CommunicationException.class, client::ping);
439+
440+
Throwable origin = exception.getCause();
441+
assertEquals(origin, client.getThumbstone());
442+
443+
testHelper.startInstance();
444+
}
445+
446+
private SocketChannelProvider makeZeroLingerProvider() {
416447
return new TestSocketChannelProvider(
417448
TarantoolTestHelper.HOST, TarantoolTestHelper.PORT, RESTART_TIMEOUT
418449
).setSoLinger(0);
419450
}
420451

421-
TarantoolClient makeClient(SocketChannelProvider provider) {
452+
private SocketChannelProvider makeErroredProvider(RuntimeException error) {
453+
return new SocketChannelProvider() {
454+
private final SocketChannelProvider delegate = makeZeroLingerProvider();
455+
private AtomicReference<RuntimeException> errorReference = new AtomicReference<>(error);
456+
457+
@Override
458+
public SocketChannel get(int retryNumber, Throwable lastError) {
459+
RuntimeException rawError = errorReference.get();
460+
if (rawError != null) {
461+
throw rawError;
462+
}
463+
return delegate.get(retryNumber, lastError);
464+
}
465+
};
466+
}
467+
468+
private TarantoolClient makeClient(SocketChannelProvider provider) {
422469
return new TarantoolClientImpl(provider, makeDefaultClientConfig());
423470
}
424471

0 commit comments

Comments
 (0)