@@ -566,10 +566,10 @@ public void operationComplete(ChannelFuture cf) {
566566 int requestTimeout = requestTimeoutInMs (config , future .getRequest ().getPerRequestConfig ());
567567 int schedulePeriod = requestTimeout != -1 ? (config .getIdleConnectionTimeoutInMs () != -1 ? Math .min (requestTimeout , config .getIdleConnectionTimeoutInMs ()) : requestTimeout ) : config .getIdleConnectionTimeoutInMs ();
568568 if (schedulePeriod != -1 && !future .isDone () && !future .isCancelled ()) {
569- ReaperFuture reaperFuture = new ReaperFuture (future );
570- Future <?> scheduledFuture = config .reaper ().scheduleAtFixedRate (reaperFuture , 0 , schedulePeriod , TimeUnit .MILLISECONDS );
571- reaperFuture .setScheduledFuture (scheduledFuture );
572- future .setReaperFuture ( reaperFuture );
569+ Reaper reaper = new Reaper (future );
570+ Future <?> scheduledFuture = config .reaper ().scheduleAtFixedRate (reaper , 0 , schedulePeriod , TimeUnit .MILLISECONDS );
571+ reaper .setScheduledFuture (scheduledFuture );
572+ future .setReaper ( reaper );
573573 }
574574 } catch (RejectedExecutionException ex ) {
575575 abort (future , ex );
@@ -866,7 +866,7 @@ public void close() {
866866 ChannelHandlerContext ctx = channel .getPipeline ().getContext (NettyAsyncHttpProvider .class );
867867 if (ctx .getAttachment () instanceof NettyResponseFuture <?>) {
868868 NettyResponseFuture <?> future = (NettyResponseFuture <?>) ctx .getAttachment ();
869- future .setReaperFuture (null );
869+ future .setReaper (null );
870870 }
871871 }
872872
@@ -1726,54 +1726,23 @@ public void operationProgressed(ChannelFuture cf, long amount, long current, lon
17261726 * Because some implementation of the ThreadSchedulingService do not clean up cancel task until they try to run them, we wrap the task with the future so the when the NettyResponseFuture cancel the reaper future this wrapper will release the references to the channel and the
17271727 * nettyResponseFuture immediately. Otherwise, the memory referenced this way will only be released after the request timeout period which can be arbitrary long.
17281728 */
1729- private final class ReaperFuture implements Future , Runnable {
1729+ public final class Reaper implements Runnable {
17301730 private Future scheduledFuture ;
17311731 private NettyResponseFuture <?> nettyResponseFuture ;
17321732
1733- public ReaperFuture (NettyResponseFuture <?> nettyResponseFuture ) {
1733+ public Reaper (NettyResponseFuture <?> nettyResponseFuture ) {
17341734 this .nettyResponseFuture = nettyResponseFuture ;
17351735 }
17361736
17371737 public void setScheduledFuture (Future scheduledFuture ) {
17381738 this .scheduledFuture = scheduledFuture ;
17391739 }
17401740
1741- /**
1742- * @Override
1743- */
17441741 public boolean cancel (boolean mayInterruptIfRunning ) {
17451742 nettyResponseFuture = null ;
17461743 return scheduledFuture .cancel (mayInterruptIfRunning );
17471744 }
17481745
1749- /**
1750- * @Override
1751- */
1752- public Object get () throws InterruptedException , ExecutionException {
1753- return scheduledFuture .get ();
1754- }
1755-
1756- /**
1757- * @Override
1758- */
1759- public Object get (long timeout , TimeUnit unit ) throws InterruptedException , ExecutionException , TimeoutException {
1760- return scheduledFuture .get (timeout , unit );
1761- }
1762-
1763- /**
1764- * @Override
1765- */
1766- public boolean isCancelled () {
1767- return scheduledFuture .isCancelled ();
1768- }
1769-
1770- /**
1771- * @Override
1772- */
1773- public boolean isDone () {
1774- return scheduledFuture .isDone ();
1775- }
1776-
17771746 private void expire (String message ) {
17781747 log .debug ("{} for {}" , message , nettyResponseFuture );
17791748 abort (nettyResponseFuture , new TimeoutException (message ));
@@ -1800,6 +1769,7 @@ public synchronized void run() {
18001769 if (nettyResponseFuture .hasRequestTimedOut (now ))
18011770 message = "Request reached time out of " + nettyResponseFuture .getRequestTimeoutInMs () + " ms after " + age + " ms" ;
18021771 else
1772+ // If the Reaper wakes up, there's only 2 possibilities: request timeout or idle
18031773 message = "Request reached idle time out of " + nettyResponseFuture .getIdleConnectionTimeoutInMs () + " ms after " + age + " ms" ;
18041774 expire (message );
18051775
0 commit comments