Skip to content

Commit 7747144

Browse files
authored
Don't report connectionAcquired until actually connected. (square#3566)
Currently our implementation acquires the connection early so that we have something to close if the call is canceled. Event listeners are simpler if they only get a connectionAcquired event once the connection has been actually established.
1 parent 6f029dd commit 7747144

File tree

4 files changed

+27
-17
lines changed

4 files changed

+27
-17
lines changed

okhttp-tests/src/test/java/okhttp3/ConnectionPoolTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public final class ConnectionPoolTest {
8585
synchronized (pool) {
8686
StreamAllocation streamAllocation = new StreamAllocation(pool, addressA, null,
8787
EventListener.NONE, null);
88-
streamAllocation.acquire(c1);
88+
streamAllocation.acquire(c1, true);
8989
}
9090

9191
// Running at time 50, the pool returns that nothing can be evicted until time 150.
@@ -179,7 +179,7 @@ private void allocateAndLeakAllocation(ConnectionPool pool, RealConnection conne
179179
synchronized (pool) {
180180
StreamAllocation leak = new StreamAllocation(pool, connection.route().address(), null,
181181
EventListener.NONE, null);
182-
leak.acquire(connection);
182+
leak.acquire(connection, true);
183183
}
184184
}
185185

okhttp-tests/src/test/java/okhttp3/EventListenerTest.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public final class EventListenerTest {
113113
response.body().close();
114114

115115
List<String> expectedEvents = Arrays.asList("CallStart", "DnsStart", "DnsEnd",
116-
"ConnectionAcquired", "ConnectStart", "ConnectEnd", "RequestHeadersStart",
116+
"ConnectStart", "ConnectEnd", "ConnectionAcquired", "RequestHeadersStart",
117117
"RequestHeadersEnd", "ResponseHeadersStart", "ResponseHeadersEnd", "ResponseBodyStart",
118118
"ResponseBodyEnd", "ConnectionReleased", "CallEnd");
119119
assertEquals(expectedEvents, listener.recordedEventTypes());
@@ -144,7 +144,7 @@ public final class EventListenerTest {
144144
completionLatch.await();
145145

146146
List<String> expectedEvents = Arrays.asList("CallStart", "DnsStart", "DnsEnd",
147-
"ConnectionAcquired", "ConnectStart", "ConnectEnd", "RequestHeadersStart",
147+
"ConnectStart", "ConnectEnd", "ConnectionAcquired", "RequestHeadersStart",
148148
"RequestHeadersEnd", "ResponseHeadersStart", "ResponseHeadersEnd", "ResponseBodyStart",
149149
"ResponseBodyEnd", "ConnectionReleased", "CallEnd");
150150
assertEquals(expectedEvents, listener.recordedEventTypes());
@@ -166,7 +166,7 @@ public final class EventListenerTest {
166166
}
167167

168168
List<String> expectedEvents = Arrays.asList("CallStart", "DnsStart", "DnsEnd",
169-
"ConnectionAcquired", "ConnectStart", "ConnectEnd", "RequestHeadersStart",
169+
"ConnectStart", "ConnectEnd", "ConnectionAcquired", "RequestHeadersStart",
170170
"RequestHeadersEnd", "ResponseHeadersStart", "ConnectionReleased", "CallFailed");
171171
assertEquals(expectedEvents, listener.recordedEventTypes());
172172
}
@@ -198,8 +198,8 @@ private void assertSuccessfulEventOrder(Matcher<Response> responseMatcher) throw
198198

199199
assumeThat(response, responseMatcher);
200200

201-
List<String> expectedEvents = asList("CallStart", "DnsStart", "DnsEnd", "ConnectionAcquired",
202-
"ConnectStart", "SecureConnectStart", "SecureConnectEnd", "ConnectEnd",
201+
List<String> expectedEvents = asList("CallStart", "DnsStart", "DnsEnd", "ConnectStart",
202+
"SecureConnectStart", "SecureConnectEnd", "ConnectEnd", "ConnectionAcquired",
203203
"RequestHeadersStart", "RequestHeadersEnd", "ResponseHeadersStart", "ResponseHeadersEnd",
204204
"ResponseBodyStart", "ResponseBodyEnd", "ConnectionReleased", "CallEnd");
205205

@@ -239,7 +239,8 @@ private void assertBytesReadWritten(RecordingEventListener listener,
239239
RequestHeadersEnd responseHeadersEnd = listener.removeUpToEvent(RequestHeadersEnd.class);
240240
assertThat("request header length", responseHeadersEnd.headerLength, requestHeaderLength);
241241
} else {
242-
assertFalse("Found RequestHeadersEnd", listener.recordedEventTypes().contains("RequestHeadersEnd"));
242+
assertFalse("Found RequestHeadersEnd",
243+
listener.recordedEventTypes().contains("RequestHeadersEnd"));
243244
}
244245

245246
if (requestBodyBytes != null) {
@@ -253,14 +254,16 @@ private void assertBytesReadWritten(RecordingEventListener listener,
253254
ResponseHeadersEnd responseHeadersEnd = listener.removeUpToEvent(ResponseHeadersEnd.class);
254255
assertThat("response header length", responseHeadersEnd.headerLength, responseHeaderLength);
255256
} else {
256-
assertFalse("Found ResponseHeadersEnd", listener.recordedEventTypes().contains("ResponseHeadersEnd"));
257+
assertFalse("Found ResponseHeadersEnd",
258+
listener.recordedEventTypes().contains("ResponseHeadersEnd"));
257259
}
258260

259261
if (responseBodyBytes != null) {
260262
ResponseBodyEnd responseBodyEnd = listener.removeUpToEvent(ResponseBodyEnd.class);
261263
assertThat("response body bytes", responseBodyEnd.bytesRead, responseBodyBytes);
262264
} else {
263-
assertFalse("Found ResponseBodyEnd", listener.recordedEventTypes().contains("ResponseBodyEnd"));
265+
assertFalse("Found ResponseBodyEnd",
266+
listener.recordedEventTypes().contains("ResponseBodyEnd"));
264267
}
265268
}
266269

okhttp/src/main/java/okhttp3/ConnectionPool.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ public synchronized int connectionCount() {
123123
assert (Thread.holdsLock(this));
124124
for (RealConnection connection : connections) {
125125
if (connection.isEligible(address, route)) {
126-
streamAllocation.acquire(connection);
126+
streamAllocation.acquire(connection, true);
127127
return connection;
128128
}
129129
}

okhttp/src/main/java/okhttp3/internal/connection/StreamAllocation.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ public final class StreamAllocation {
8787
private final RouteSelector routeSelector;
8888
private int refusedStreamCount;
8989
private RealConnection connection;
90+
private boolean reportedAcquired;
9091
private boolean released;
9192
private boolean canceled;
9293
private HttpCodec codec;
@@ -176,6 +177,10 @@ private RealConnection findConnection(int connectTimeout, int readTimeout, int w
176177
result = this.connection;
177178
releasedConnection = null;
178179
}
180+
if (!reportedAcquired) {
181+
// If the connection was never reported acquired, don't report it as released!
182+
releasedConnection = null;
183+
}
179184

180185
if (result == null) {
181186
// Attempt to get a connection from the pool.
@@ -237,15 +242,13 @@ private RealConnection findConnection(int connectTimeout, int readTimeout, int w
237242
route = selectedRoute;
238243
refusedStreamCount = 0;
239244
result = new RealConnection(connectionPool, selectedRoute);
240-
acquire(result);
245+
acquire(result, false);
241246
}
242247
}
243248

244-
// We have a connection. Either a connected one from the pool, or one we need to connect.
245-
eventListener.connectionAcquired(call, result);
246-
247249
// If we found a pooled connection on the 2nd time around, we're done.
248250
if (foundPooledConnection) {
251+
eventListener.connectionAcquired(call, result);
249252
return result;
250253
}
251254

@@ -256,6 +259,8 @@ private RealConnection findConnection(int connectTimeout, int readTimeout, int w
256259

257260
Socket socket = null;
258261
synchronized (connectionPool) {
262+
reportedAcquired = true;
263+
259264
// Pool the connection.
260265
Internal.instance.put(connectionPool, result);
261266

@@ -268,6 +273,7 @@ private RealConnection findConnection(int connectTimeout, int readTimeout, int w
268273
}
269274
closeQuietly(socket);
270275

276+
eventListener.connectionAcquired(call, result);
271277
return result;
272278
}
273279

@@ -440,7 +446,7 @@ public void streamFailed(IOException e) {
440446
}
441447
releasedConnection = connection;
442448
socket = deallocate(noNewStreams, false, true);
443-
if (connection != null) releasedConnection = null;
449+
if (connection != null || !reportedAcquired) releasedConnection = null;
444450
}
445451

446452
closeQuietly(socket);
@@ -453,11 +459,12 @@ public void streamFailed(IOException e) {
453459
* Use this allocation to hold {@code connection}. Each call to this must be paired with a call to
454460
* {@link #release} on the same connection.
455461
*/
456-
public void acquire(RealConnection connection) {
462+
public void acquire(RealConnection connection, boolean reportedAcquired) {
457463
assert (Thread.holdsLock(connectionPool));
458464
if (this.connection != null) throw new IllegalStateException();
459465

460466
this.connection = connection;
467+
this.reportedAcquired = reportedAcquired;
461468
connection.allocations.add(new StreamAllocationReference(this, callStackTrace));
462469
}
463470

0 commit comments

Comments
 (0)