1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.http.impl.execchain;
29
30 import java.io.IOException;
31 import java.lang.reflect.UndeclaredThrowableException;
32
33 import org.apache.http.HttpException;
34 import org.apache.http.annotation.Immutable;
35 import org.apache.http.client.BackoffManager;
36 import org.apache.http.client.ConnectionBackoffStrategy;
37 import org.apache.http.client.methods.CloseableHttpResponse;
38 import org.apache.http.client.methods.HttpExecutionAware;
39 import org.apache.http.client.methods.HttpRequestWrapper;
40 import org.apache.http.client.protocol.HttpClientContext;
41 import org.apache.http.conn.routing.HttpRoute;
42 import org.apache.http.util.Args;
43
44
45
46
47 @Immutable
48 public class BackoffStrategyExec implements ClientExecChain {
49
50 private final ClientExecChain requestExecutor;
51 private final ConnectionBackoffStrategy connectionBackoffStrategy;
52 private final BackoffManager backoffManager;
53
54 public BackoffStrategyExec(
55 final ClientExecChain requestExecutor,
56 final ConnectionBackoffStrategy connectionBackoffStrategy,
57 final BackoffManager backoffManager) {
58 super();
59 Args.notNull(requestExecutor, "HTTP client request executor");
60 Args.notNull(connectionBackoffStrategy, "Connection backoff strategy");
61 Args.notNull(backoffManager, "Backoff manager");
62 this.requestExecutor = requestExecutor;
63 this.connectionBackoffStrategy = connectionBackoffStrategy;
64 this.backoffManager = backoffManager;
65 }
66
67 public CloseableHttpResponse execute(
68 final HttpRoute route,
69 final HttpRequestWrapper request,
70 final HttpClientContext context,
71 final HttpExecutionAware execAware) throws IOException, HttpException {
72 Args.notNull(route, "HTTP route");
73 Args.notNull(request, "HTTP request");
74 Args.notNull(context, "HTTP context");
75 CloseableHttpResponse out = null;
76 try {
77 out = this.requestExecutor.execute(route, request, context, execAware);
78 } catch (final Exception ex) {
79 if (out != null) {
80 out.close();
81 }
82 if (this.connectionBackoffStrategy.shouldBackoff(ex)) {
83 this.backoffManager.backOff(route);
84 }
85 if (ex instanceof RuntimeException) {
86 throw (RuntimeException) ex;
87 }
88 if (ex instanceof HttpException) {
89 throw (HttpException) ex;
90 }
91 if (ex instanceof IOException) {
92 throw (IOException) ex;
93 }
94 throw new UndeclaredThrowableException(ex);
95 }
96 if (this.connectionBackoffStrategy.shouldBackoff(out)) {
97 this.backoffManager.backOff(route);
98 } else {
99 this.backoffManager.probe(route);
100 }
101 return out;
102 }
103
104 }