Skip to content

Commit 8ad4836

Browse files
committed
8361249: PlainHttpConnection connection logic can be simplified
Reviewed-by: djelinski, vyazici, michaelm, jpai
1 parent d75ea7e commit 8ad4836

File tree

1 file changed

+8
-58
lines changed

1 file changed

+8
-58
lines changed

src/java.net.http/share/classes/jdk/internal/net/http/PlainHttpConnection.java

Lines changed: 8 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,10 @@
3636
import java.util.concurrent.CompletableFuture;
3737
import java.util.concurrent.atomic.AtomicReference;
3838
import java.util.concurrent.locks.ReentrantLock;
39-
import java.util.function.Function;
4039

4140
import jdk.internal.net.http.common.FlowTube;
4241
import jdk.internal.net.http.common.Log;
4342
import jdk.internal.net.http.common.MinimalFuture;
44-
import jdk.internal.net.http.common.TimeSource;
4543
import jdk.internal.net.http.common.Utils;
4644

4745
/**
@@ -57,16 +55,9 @@ class PlainHttpConnection extends HttpConnection {
5755
private volatile boolean connected;
5856
private volatile boolean closed;
5957
private volatile ConnectTimerEvent connectTimerEvent; // may be null
60-
private volatile int unsuccessfulAttempts;
6158
private final ReentrantLock stateLock = new ReentrantLock();
6259
private final AtomicReference<Throwable> errorRef = new AtomicReference<>();
6360

64-
// Indicates whether a connection attempt has succeeded or should be retried.
65-
// If the attempt failed, and shouldn't be retried, there will be an exception
66-
// instead.
67-
private enum ConnectState { SUCCESS, RETRY }
68-
69-
7061
/**
7162
* Returns a ConnectTimerEvent iff there is a connect timeout duration,
7263
* otherwise null.
@@ -115,10 +106,10 @@ Throwable getError(Throwable cause) {
115106
}
116107

117108
final class ConnectEvent extends AsyncEvent {
118-
private final CompletableFuture<ConnectState> cf;
109+
private final CompletableFuture<Void> cf;
119110
private final Exchange<?> exchange;
120111

121-
ConnectEvent(CompletableFuture<ConnectState> cf, Exchange<?> exchange) {
112+
ConnectEvent(CompletableFuture<Void> cf, Exchange<?> exchange) {
122113
this.cf = cf;
123114
this.exchange = exchange;
124115
}
@@ -147,15 +138,10 @@ public void handle() {
147138
assert finished || exchange.multi.requestCancelled() : "Expected channel to be connected";
148139
if (connectionOpened()) {
149140
// complete async since the event runs on the SelectorManager thread
150-
cf.completeAsync(() -> ConnectState.SUCCESS, client().theExecutor());
141+
if (debug.on()) debug.log("%s has been connected asynchronously", label());
142+
cf.completeAsync(() -> null, client().theExecutor());
151143
} else throw new ConnectException("Connection closed");
152144
} catch (Throwable e) {
153-
if (canRetryConnect(e)) {
154-
unsuccessfulAttempts++;
155-
// complete async since the event runs on the SelectorManager thread
156-
cf.completeAsync(() -> ConnectState.RETRY, client().theExecutor());
157-
return;
158-
}
159145
Throwable t = getError(Utils.toConnectException(e));
160146
// complete async since the event runs on the SelectorManager thread
161147
client().theExecutor().execute( () -> cf.completeExceptionally(t));
@@ -174,7 +160,7 @@ public void abort(IOException ioe) {
174160

175161
@Override
176162
public CompletableFuture<Void> connectAsync(Exchange<?> exchange) {
177-
CompletableFuture<ConnectState> cf = new MinimalFuture<>();
163+
CompletableFuture<Void> cf = new MinimalFuture<>();
178164
try {
179165
assert !connected : "Already connected";
180166
assert !chan.isBlocking() : "Unexpected blocking channel";
@@ -212,7 +198,8 @@ public CompletableFuture<Void> connectAsync(Exchange<?> exchange) {
212198
if (finished) {
213199
if (debug.on()) debug.log("connect finished without blocking");
214200
if (connectionOpened()) {
215-
cf.complete(ConnectState.SUCCESS);
201+
if (debug.on()) debug.log("%s has been connected", label());
202+
cf.complete(null);
216203
} else throw getError(new ConnectException("connection closed"));
217204
} else {
218205
if (debug.on()) debug.log("registering connect event");
@@ -232,8 +219,7 @@ public CompletableFuture<Void> connectAsync(Exchange<?> exchange) {
232219
debug.log("Failed to close channel after unsuccessful connect");
233220
}
234221
}
235-
return cf.handle((r,t) -> checkRetryConnect(r, t, exchange))
236-
.thenCompose(Function.identity());
222+
return cf;
237223
}
238224

239225
boolean connectionOpened() {
@@ -254,42 +240,6 @@ boolean connectionOpened() {
254240
return !closed;
255241
}
256242

257-
/**
258-
* On some platforms, a ConnectEvent may be raised and a ConnectionException
259-
* may occur with the message "Connection timed out: no further information"
260-
* before our actual connection timeout has expired. In this case, this
261-
* method will be called with a {@code connect} state of {@code ConnectState.RETRY)}
262-
* and we will retry once again.
263-
* @param connect indicates whether the connection was successful or should be retried
264-
* @param failed the failure if the connection failed
265-
* @param exchange the exchange
266-
* @return a completable future that will take care of retrying the connection if needed.
267-
*/
268-
private CompletableFuture<Void> checkRetryConnect(ConnectState connect, Throwable failed, Exchange<?> exchange) {
269-
// first check if the connection failed
270-
if (failed != null) return MinimalFuture.failedFuture(failed);
271-
// then check if the connection should be retried
272-
if (connect == ConnectState.RETRY) {
273-
int attempts = unsuccessfulAttempts;
274-
assert attempts <= 1;
275-
if (debug.on())
276-
debug.log("Retrying connect after %d attempts", attempts);
277-
return connectAsync(exchange);
278-
}
279-
// Otherwise, the connection was successful;
280-
assert connect == ConnectState.SUCCESS;
281-
return MinimalFuture.completedFuture(null);
282-
}
283-
284-
private boolean canRetryConnect(Throwable e) {
285-
if (!MultiExchange.RETRY_CONNECT) return false;
286-
if (!(e instanceof ConnectException)) return false;
287-
if (unsuccessfulAttempts > 0) return false;
288-
ConnectTimerEvent timer = connectTimerEvent;
289-
if (timer == null) return true;
290-
return timer.deadline().isAfter(TimeSource.now());
291-
}
292-
293243
@Override
294244
public CompletableFuture<Void> finishConnect() {
295245
assert connected == false;

0 commit comments

Comments
 (0)