Skip to content

Commit 178ec0d

Browse files
author
oleksiys
committed
+ rework the cleanup process.
related to the AsyncHttpClient#1133
1 parent f720f33 commit 178ec0d

File tree

1 file changed

+40
-45
lines changed

1 file changed

+40
-45
lines changed

src/main/java/com/ning/http/client/providers/grizzly/HttpTransactionContext.java

Lines changed: 40 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
import com.ning.http.util.AsyncHttpProviderUtils;
2222
import com.ning.http.util.ProxyUtils;
2323
import java.io.IOException;
24-
import java.util.HashSet;
25-
import java.util.Set;
2624
import org.glassfish.grizzly.CloseListener;
2725
import org.glassfish.grizzly.CloseType;
2826
import org.glassfish.grizzly.Closeable;
@@ -86,8 +84,8 @@ public final class HttpTransactionContext {
8684
/**
8785
* <tt>true</tt> if the request is fully sent, or <tt>false</tt>otherwise.
8886
*/
89-
volatile boolean isRequestFullySent;
90-
Set<CompletionHandler<HttpTransactionContext>> reqFullySentHandlers;
87+
private boolean isRequestFullySent;
88+
private CleanupTask cleanupTask;
9189

9290
private final CloseListener listener = new CloseListener<Closeable, CloseType>() {
9391
@Override
@@ -125,24 +123,9 @@ static void cleanupTransaction(final HttpContext httpCtx,
125123

126124
assert httpTxContext != null;
127125

128-
if (httpTxContext.isRequestFullySent) {
129-
cleanupTransaction(httpCtx, httpTxContext);
130-
completionHandler.completed(httpTxContext);
131-
} else {
132-
httpTxContext.addRequestSentCompletionHandler(completionHandler);
133-
if (httpTxContext.isRequestFullySent &&
134-
httpTxContext.removeRequestSentCompletionHandler(completionHandler)) {
135-
completionHandler.completed(httpTxContext);
136-
}
137-
}
126+
httpTxContext.scheduleCleanup(httpCtx, completionHandler);
138127
}
139128

140-
static void cleanupTransaction(final HttpContext httpCtx,
141-
final HttpTransactionContext httpTxContext) {
142-
httpCtx.getCloseable().removeCloseListener(httpTxContext.listener);
143-
REQUEST_STATE_ATTR.remove(httpCtx);
144-
}
145-
146129
static HttpTransactionContext currentTransaction(
147130
final HttpHeader httpHeader) {
148131
return currentTransaction(httpHeader.getProcessingState().getHttpContext());
@@ -269,44 +252,56 @@ void closeConnection() {
269252
connection.closeSilently();
270253
}
271254

272-
private synchronized void addRequestSentCompletionHandler(
255+
private void scheduleCleanup(final HttpContext httpCtx,
273256
final CompletionHandler<HttpTransactionContext> completionHandler) {
274-
if (reqFullySentHandlers == null) {
275-
reqFullySentHandlers = new HashSet<>();
257+
synchronized (this) {
258+
if (!isRequestFullySent) {
259+
assert cleanupTask == null; // scheduleCleanup should be called only once
260+
cleanupTask = new CleanupTask(httpCtx, completionHandler);
261+
return;
262+
}
276263
}
277-
reqFullySentHandlers.add(completionHandler);
278-
}
279264

280-
private synchronized boolean removeRequestSentCompletionHandler(
281-
final CompletionHandler<HttpTransactionContext> completionHandler) {
282-
return reqFullySentHandlers != null
283-
? reqFullySentHandlers.remove(completionHandler)
284-
: false;
265+
assert isRequestFullySent;
266+
cleanup(httpCtx);
267+
completionHandler.completed(this);
285268
}
286269

287-
boolean isRequestFullySent() {
288-
return isRequestFullySent;
270+
private void cleanup(final HttpContext httpCtx) {
271+
httpCtx.getCloseable().removeCloseListener(listener);
272+
REQUEST_STATE_ATTR.remove(httpCtx);
289273
}
290274

291275
@SuppressWarnings("unchecked")
292276
void onRequestFullySent() {
293-
this.isRequestFullySent = true;
294-
295-
Object[] handlers = null;
296277
synchronized (this) {
297-
if (reqFullySentHandlers != null) {
298-
handlers = reqFullySentHandlers.toArray();
299-
reqFullySentHandlers = null;
278+
if (isRequestFullySent) {
279+
return;
300280
}
281+
282+
isRequestFullySent = true;
301283
}
302284

303-
if (handlers != null) {
304-
for (Object o : handlers) {
305-
try {
306-
((CompletionHandler<HttpTransactionContext>) o).completed(this);
307-
} catch (Exception e) {
308-
}
309-
}
285+
if (cleanupTask != null) {
286+
cleanupTask.run();
287+
}
288+
}
289+
290+
private class CleanupTask implements Runnable {
291+
private final HttpContext httpCtx;
292+
private final CompletionHandler<HttpTransactionContext> completionHandler;
293+
294+
private CleanupTask(final HttpContext httpCtx,
295+
final CompletionHandler<HttpTransactionContext> completionHandler) {
296+
this.httpCtx = httpCtx;
297+
this.completionHandler = completionHandler;
298+
}
299+
300+
@Override
301+
public void run() {
302+
cleanup(httpCtx);
303+
completionHandler.completed(HttpTransactionContext.this);
310304
}
305+
311306
}
312307
} // END HttpTransactionContext

0 commit comments

Comments
 (0)