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 package org.apache.hc.client5.http.impl.cache;
28
29 import java.io.IOException;
30 import java.util.concurrent.Future;
31 import java.util.concurrent.RejectedExecutionException;
32 import java.util.concurrent.ScheduledExecutorService;
33 import java.util.concurrent.atomic.AtomicReference;
34
35 import org.apache.hc.client5.http.async.AsyncExecCallback;
36 import org.apache.hc.client5.http.schedule.SchedulingStrategy;
37 import org.apache.hc.core5.concurrent.CompletedFuture;
38 import org.apache.hc.core5.http.EntityDetails;
39 import org.apache.hc.core5.http.HttpException;
40 import org.apache.hc.core5.http.HttpResponse;
41 import org.apache.hc.core5.http.HttpStatus;
42 import org.apache.hc.core5.http.nio.AsyncDataConsumer;
43 import org.apache.hc.core5.util.TimeValue;
44 import org.apache.hc.core5.util.Timeout;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48
49
50
51
52 class DefaultAsyncCacheRevalidator extends CacheRevalidatorBase {
53
54 private static final Logger LOG = LoggerFactory.getLogger(DefaultAsyncCacheRevalidator.class);
55
56 interface RevalidationCall {
57
58 void execute(AsyncExecCallback asyncExecCallback);
59 }
60
61 static class InternalScheduledExecutor implements ScheduledExecutor {
62
63 private final ScheduledExecutor executor;
64
65 InternalScheduledExecutor(final ScheduledExecutor executor) {
66 this.executor = executor;
67 }
68
69 @Override
70 public Future<?> schedule(final Runnable command, final TimeValue timeValue) throws RejectedExecutionException {
71 if (timeValue.toMilliseconds() <= 0) {
72 command.run();
73 return new CompletedFuture<>(null);
74 }
75 return executor.schedule(command, timeValue);
76 }
77
78 @Override
79 public void shutdown() {
80 executor.shutdown();
81 }
82
83 @Override
84 public void awaitTermination(final Timeout timeout) throws InterruptedException {
85 executor.awaitTermination(timeout);
86 }
87
88 }
89
90
91
92
93
94 public DefaultAsyncCacheRevalidator(
95 final ScheduledExecutor scheduledExecutor,
96 final SchedulingStrategy schedulingStrategy) {
97 super(new InternalScheduledExecutor(scheduledExecutor), schedulingStrategy);
98 }
99
100
101
102
103
104 public DefaultAsyncCacheRevalidator(
105 final ScheduledExecutorService executorService,
106 final SchedulingStrategy schedulingStrategy) {
107 this(wrap(executorService), schedulingStrategy);
108 }
109
110
111
112
113 public void revalidateCacheEntry(
114 final String cacheKey ,
115 final AsyncExecCallback asyncExecCallback,
116 final RevalidationCall call) {
117 scheduleRevalidation(cacheKey, () -> call.execute(new AsyncExecCallback() {
118
119 private final AtomicReference<HttpResponse> responseRef = new AtomicReference<>();
120
121 @Override
122 public AsyncDataConsumer handleResponse(
123 final HttpResponse response,
124 final EntityDetails entityDetails) throws HttpException, IOException {
125 responseRef.set(response);
126 return asyncExecCallback.handleResponse(response, entityDetails);
127 }
128
129 @Override
130 public void handleInformationResponse(
131 final HttpResponse response) throws HttpException, IOException {
132 asyncExecCallback.handleInformationResponse(response);
133 }
134
135 @Override
136 public void completed() {
137 final HttpResponse httpResponse = responseRef.getAndSet(null);
138 if (httpResponse != null && httpResponse.getCode() < HttpStatus.SC_SERVER_ERROR) {
139 jobSuccessful(cacheKey);
140 } else {
141 jobFailed(cacheKey);
142 }
143 asyncExecCallback.completed();
144 }
145
146 @Override
147 public void failed(final Exception cause) {
148 if (cause instanceof IOException) {
149 LOG.debug("Asynchronous revalidation failed due to I/O error", cause);
150 } else if (cause instanceof HttpException) {
151 LOG.error("HTTP protocol exception during asynchronous revalidation", cause);
152 } else {
153 LOG.error("Unexpected runtime exception thrown during asynchronous revalidation", cause);
154 }
155 try {
156 jobFailed(cacheKey);
157 } finally {
158 asyncExecCallback.failed(cause);
159 }
160 }
161
162 }));
163 }
164
165 }