@@ -566,10 +566,10 @@ public void operationComplete(ChannelFuture cf) {
566
566
int requestTimeout = requestTimeoutInMs (config , future .getRequest ().getPerRequestConfig ());
567
567
int schedulePeriod = requestTimeout != -1 ? (config .getIdleConnectionTimeoutInMs () != -1 ? Math .min (requestTimeout , config .getIdleConnectionTimeoutInMs ()) : requestTimeout ) : config .getIdleConnectionTimeoutInMs ();
568
568
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 );
573
573
}
574
574
} catch (RejectedExecutionException ex ) {
575
575
abort (future , ex );
@@ -866,7 +866,7 @@ public void close() {
866
866
ChannelHandlerContext ctx = channel .getPipeline ().getContext (NettyAsyncHttpProvider .class );
867
867
if (ctx .getAttachment () instanceof NettyResponseFuture <?>) {
868
868
NettyResponseFuture <?> future = (NettyResponseFuture <?>) ctx .getAttachment ();
869
- future .setReaperFuture (null );
869
+ future .setReaper (null );
870
870
}
871
871
}
872
872
@@ -1726,54 +1726,23 @@ public void operationProgressed(ChannelFuture cf, long amount, long current, lon
1726
1726
* 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
1727
1727
* nettyResponseFuture immediately. Otherwise, the memory referenced this way will only be released after the request timeout period which can be arbitrary long.
1728
1728
*/
1729
- private final class ReaperFuture implements Future , Runnable {
1729
+ public final class Reaper implements Runnable {
1730
1730
private Future scheduledFuture ;
1731
1731
private NettyResponseFuture <?> nettyResponseFuture ;
1732
1732
1733
- public ReaperFuture (NettyResponseFuture <?> nettyResponseFuture ) {
1733
+ public Reaper (NettyResponseFuture <?> nettyResponseFuture ) {
1734
1734
this .nettyResponseFuture = nettyResponseFuture ;
1735
1735
}
1736
1736
1737
1737
public void setScheduledFuture (Future scheduledFuture ) {
1738
1738
this .scheduledFuture = scheduledFuture ;
1739
1739
}
1740
1740
1741
- /**
1742
- * @Override
1743
- */
1744
1741
public boolean cancel (boolean mayInterruptIfRunning ) {
1745
1742
nettyResponseFuture = null ;
1746
1743
return scheduledFuture .cancel (mayInterruptIfRunning );
1747
1744
}
1748
1745
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
-
1777
1746
private void expire (String message ) {
1778
1747
log .debug ("{} for {}" , message , nettyResponseFuture );
1779
1748
abort (nettyResponseFuture , new TimeoutException (message ));
@@ -1800,6 +1769,7 @@ public synchronized void run() {
1800
1769
if (nettyResponseFuture .hasRequestTimedOut (now ))
1801
1770
message = "Request reached time out of " + nettyResponseFuture .getRequestTimeoutInMs () + " ms after " + age + " ms" ;
1802
1771
else
1772
+ // If the Reaper wakes up, there's only 2 possibilities: request timeout or idle
1803
1773
message = "Request reached idle time out of " + nettyResponseFuture .getIdleConnectionTimeoutInMs () + " ms after " + age + " ms" ;
1804
1774
expire (message );
1805
1775
0 commit comments