View Javadoc

1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.http.impl.client.cache;
28  
29  import org.apache.http.util.Args;
30  
31  /**
32   * <p>Java Beans-style configuration for a {@link CachingHttpClient}. Any class
33   * in the caching module that has configuration options should take a
34   * {@link CacheConfig} argument in one of its constructors. A
35   * {@code CacheConfig} instance has sane and conservative defaults, so the
36   * easiest way to specify options is to get an instance and then set just
37   * the options you want to modify from their defaults.</p>
38   *
39   * <p><b>N.B.</b> This class is only for caching-specific configuration; to
40   * configure the behavior of the rest of the client, configure the
41   * {@link org.apache.http.client.HttpClient} used as the &quot;backend&quot;
42   * for the {@code CachingHttpClient}.</p>
43   *
44   * <p>Cache configuration can be grouped into the following categories:</p>
45   *
46   * <p><b>Cache size.</b> If the backend storage supports these limits, you
47   * can specify the {@link CacheConfig#getMaxCacheEntries maximum number of
48   * cache entries} as well as the {@link CacheConfig#getMaxObjectSizeBytes
49   * maximum cacheable response body size}.</p>
50   *
51   * <p><b>Public/private caching.</b> By default, the caching module considers
52   * itself to be a shared (public) cache, and will not, for example, cache
53   * responses to requests with {@code Authorization} headers or responses
54   * marked with {@code Cache-Control: private}. If, however, the cache
55   * is only going to be used by one logical "user" (behaving similarly to a
56   * browser cache), then you will want to {@link
57   * CacheConfig#setSharedCache(boolean) turn off the shared cache setting}.</p>
58   *
59   * <p><b>Heuristic caching</b>. Per RFC2616, a cache may cache certain cache
60   * entries even if no explicit cache control headers are set by the origin.
61   * This behavior is off by default, but you may want to turn this on if you
62   * are working with an origin that doesn't set proper headers but where you
63   * still want to cache the responses. You will want to {@link
64   * CacheConfig#setHeuristicCachingEnabled(boolean) enable heuristic caching},
65   * then specify either a {@link CacheConfig#getHeuristicDefaultLifetime()
66   * default freshness lifetime} and/or a {@link
67   * CacheConfig#setHeuristicCoefficient(float) fraction of the time since
68   * the resource was last modified}. See Sections
69   * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.2.2">
70   * 13.2.2</a> and <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.2.4">
71   * 13.2.4</a> of the HTTP/1.1 RFC for more details on heuristic caching.</p>
72   *
73   * <p><b>Background validation</b>. The cache module supports the
74   * {@code stale-while-revalidate} directive of
75   * <a href="http://tools.ietf.org/html/rfc5861">RFC5861</a>, which allows
76   * certain cache entry revalidations to happen in the background. You may
77   * want to tweak the settings for the {@link
78   * CacheConfig#getAsynchronousWorkersCore() minimum} and {@link
79   * CacheConfig#getAsynchronousWorkersMax() maximum} number of background
80   * worker threads, as well as the {@link
81   * CacheConfig#getAsynchronousWorkerIdleLifetimeSecs() maximum time they
82   * can be idle before being reclaimed}. You can also control the {@link
83   * CacheConfig#getRevalidationQueueSize() size of the queue} used for
84   * revalidations when there aren't enough workers to keep up with demand.</b>
85   */
86  public class CacheConfig implements Cloneable {
87  
88      /** Default setting for the maximum object size that will be
89       * cached, in bytes.
90       */
91      public final static int DEFAULT_MAX_OBJECT_SIZE_BYTES = 8192;
92  
93      /** Default setting for the maximum number of cache entries
94       * that will be retained.
95       */
96      public final static int DEFAULT_MAX_CACHE_ENTRIES = 1000;
97  
98      /** Default setting for the number of retries on a failed
99       * cache update
100      */
101     public final static int DEFAULT_MAX_UPDATE_RETRIES = 1;
102 
103     /** Default setting for heuristic caching
104      */
105     public final static boolean DEFAULT_HEURISTIC_CACHING_ENABLED = false;
106 
107     /** Default coefficient used to heuristically determine freshness
108      * lifetime from the Last-Modified time of a cache entry.
109      */
110     public final static float DEFAULT_HEURISTIC_COEFFICIENT = 0.1f;
111 
112     /** Default lifetime in seconds to be assumed when we cannot calculate
113      * freshness heuristically.
114      */
115     public final static long DEFAULT_HEURISTIC_LIFETIME = 0;
116 
117     /** Default number of worker threads to allow for background revalidations
118      * resulting from the stale-while-revalidate directive.
119      */
120     public static final int DEFAULT_ASYNCHRONOUS_WORKERS_MAX = 1;
121 
122     /** Default minimum number of worker threads to allow for background
123      * revalidations resulting from the stale-while-revalidate directive.
124      */
125     public static final int DEFAULT_ASYNCHRONOUS_WORKERS_CORE = 1;
126 
127     /** Default maximum idle lifetime for a background revalidation thread
128      * before it gets reclaimed.
129      */
130     public static final int DEFAULT_ASYNCHRONOUS_WORKER_IDLE_LIFETIME_SECS = 60;
131 
132     /** Default maximum queue length for background revalidation requests.
133      */
134     public static final int DEFAULT_REVALIDATION_QUEUE_SIZE = 100;
135 
136     public static final CacheConfig DEFAULT = new Builder().build();
137 
138     // TODO: make final
139     private long maxObjectSize;
140     private int maxCacheEntries;
141     private int maxUpdateRetries;
142     private boolean heuristicCachingEnabled;
143     private float heuristicCoefficient;
144     private long heuristicDefaultLifetime;
145     private boolean isSharedCache;
146     private int asynchronousWorkersMax;
147     private int asynchronousWorkersCore;
148     private int asynchronousWorkerIdleLifetimeSecs;
149     private int revalidationQueueSize;
150     private boolean neverCacheHTTP10ResponsesWithQuery;
151 
152     /**
153      * @deprecated (4.3) use {@link Builder}.
154      */
155     @Deprecated
156     public CacheConfig() {
157         super();
158         this.maxObjectSize = DEFAULT_MAX_OBJECT_SIZE_BYTES;
159         this.maxCacheEntries = DEFAULT_MAX_CACHE_ENTRIES;
160         this.maxUpdateRetries = DEFAULT_MAX_UPDATE_RETRIES;
161         this.heuristicCachingEnabled = false;
162         this.heuristicCoefficient = DEFAULT_HEURISTIC_COEFFICIENT;
163         this.heuristicDefaultLifetime = DEFAULT_HEURISTIC_LIFETIME;
164         this.isSharedCache = true;
165         this.asynchronousWorkersMax = DEFAULT_ASYNCHRONOUS_WORKERS_MAX;
166         this.asynchronousWorkersCore = DEFAULT_ASYNCHRONOUS_WORKERS_CORE;
167         this.asynchronousWorkerIdleLifetimeSecs = DEFAULT_ASYNCHRONOUS_WORKER_IDLE_LIFETIME_SECS;
168         this.revalidationQueueSize = DEFAULT_REVALIDATION_QUEUE_SIZE;
169     }
170 
171     CacheConfig(
172             final long maxObjectSize,
173             final int maxCacheEntries,
174             final int maxUpdateRetries,
175             final boolean heuristicCachingEnabled,
176             final float heuristicCoefficient,
177             final long heuristicDefaultLifetime,
178             final boolean isSharedCache,
179             final int asynchronousWorkersMax,
180             final int asynchronousWorkersCore,
181             final int asynchronousWorkerIdleLifetimeSecs,
182             final int revalidationQueueSize,
183             final boolean neverCacheHTTP10ResponsesWithQuery) {
184         super();
185         this.maxObjectSize = maxObjectSize;
186         this.maxCacheEntries = maxCacheEntries;
187         this.maxUpdateRetries = maxUpdateRetries;
188         this.heuristicCachingEnabled = heuristicCachingEnabled;
189         this.heuristicCoefficient = heuristicCoefficient;
190         this.heuristicDefaultLifetime = heuristicDefaultLifetime;
191         this.isSharedCache = isSharedCache;
192         this.asynchronousWorkersMax = asynchronousWorkersMax;
193         this.asynchronousWorkersCore = asynchronousWorkersCore;
194         this.asynchronousWorkerIdleLifetimeSecs = asynchronousWorkerIdleLifetimeSecs;
195         this.revalidationQueueSize = revalidationQueueSize;
196     }
197 
198     /**
199      * Returns the current maximum response body size that will be cached.
200      * @return size in bytes
201      *
202      * @deprecated (4.2)  use {@link #getMaxObjectSize()}
203      */
204     @Deprecated
205     public int getMaxObjectSizeBytes() {
206         return maxObjectSize > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) maxObjectSize;
207     }
208 
209     /**
210      * Specifies the maximum response body size that will be eligible for caching.
211      * @param maxObjectSizeBytes size in bytes
212      *
213      * @deprecated (4.2)  use {@link Builder}.
214      */
215     @Deprecated
216     public void setMaxObjectSizeBytes(final int maxObjectSizeBytes) {
217         if (maxObjectSizeBytes > Integer.MAX_VALUE) {
218             this.maxObjectSize = Integer.MAX_VALUE;
219         } else {
220             this.maxObjectSize = maxObjectSizeBytes;
221         }
222     }
223 
224     /**
225      * Returns the current maximum response body size that will be cached.
226      * @return size in bytes
227      *
228      * @since 4.2
229      */
230     public long getMaxObjectSize() {
231         return maxObjectSize;
232     }
233 
234     /**
235      * Specifies the maximum response body size that will be eligible for caching.
236      * @param maxObjectSize size in bytes
237      *
238      * @since 4.2
239      *
240      * @deprecated (4.3) use {@link Builder}.
241      */
242     @Deprecated
243     public void setMaxObjectSize(final long maxObjectSize) {
244         this.maxObjectSize = maxObjectSize;
245     }
246 
247     /**
248      * Returns whether the cache will never cache HTTP 1.0 responses with a query string or not.
249      * @return {@code true} to not cache query string responses, {@code false} to cache if explicit cache headers are
250      * found
251      */
252     public boolean isNeverCacheHTTP10ResponsesWithQuery() {
253         return neverCacheHTTP10ResponsesWithQuery;
254     }
255 
256     /**
257      * Returns the maximum number of cache entries the cache will retain.
258      */
259     public int getMaxCacheEntries() {
260         return maxCacheEntries;
261     }
262 
263     /**
264      * Sets the maximum number of cache entries the cache will retain.
265      *
266      * @deprecated (4.3) use {@link Builder}.
267      */
268     @Deprecated
269     public void setMaxCacheEntries(final int maxCacheEntries) {
270         this.maxCacheEntries = maxCacheEntries;
271     }
272 
273     /**
274      * Returns the number of times to retry a cache update on failure
275      */
276     public int getMaxUpdateRetries(){
277         return maxUpdateRetries;
278     }
279 
280     /**
281      * Sets the number of times to retry a cache update on failure
282      *
283      * @deprecated (4.3) use {@link Builder}.
284      */
285     @Deprecated
286     public void setMaxUpdateRetries(final int maxUpdateRetries){
287         this.maxUpdateRetries = maxUpdateRetries;
288     }
289 
290     /**
291      * Returns whether heuristic caching is enabled.
292      * @return {@code true} if it is enabled.
293      */
294     public boolean isHeuristicCachingEnabled() {
295         return heuristicCachingEnabled;
296     }
297 
298     /**
299      * Enables or disables heuristic caching.
300      * @param heuristicCachingEnabled should be {@code true} to
301      *   permit heuristic caching, {@code false} to enable it.
302      *
303      * @deprecated (4.3) use {@link Builder}.
304      */
305     @Deprecated
306     public void setHeuristicCachingEnabled(final boolean heuristicCachingEnabled) {
307         this.heuristicCachingEnabled = heuristicCachingEnabled;
308     }
309 
310     /**
311      * Returns lifetime coefficient used in heuristic freshness caching.
312      */
313     public float getHeuristicCoefficient() {
314         return heuristicCoefficient;
315     }
316 
317     /**
318      * Sets coefficient to be used in heuristic freshness caching. This is
319      * interpreted as the fraction of the time between the {@code Last-Modified}
320      * and {@code Date} headers of a cached response during which the cached
321      * response will be considered heuristically fresh.
322      * @param heuristicCoefficient should be between {@code 0.0} and
323      *   {@code 1.0}.
324      *
325      * @deprecated (4.3) use {@link Builder}.
326      */
327     @Deprecated
328     public void setHeuristicCoefficient(final float heuristicCoefficient) {
329         this.heuristicCoefficient = heuristicCoefficient;
330     }
331 
332     /**
333      * Get the default lifetime to be used if heuristic freshness calculation is
334      * not possible.
335      */
336     public long getHeuristicDefaultLifetime() {
337         return heuristicDefaultLifetime;
338     }
339 
340     /**
341      * Sets default lifetime in seconds to be used if heuristic freshness
342      * calculation is not possible. Explicit cache control directives on
343      * either the request or origin response will override this, as will
344      * the heuristic {@code Last-Modified} freshness calculation if it is
345      * available.
346      * @param heuristicDefaultLifetimeSecs is the number of seconds to
347      *   consider a cache-eligible response fresh in the absence of other
348      *   information. Set this to {@code 0} to disable this style of
349      *   heuristic caching.
350      *
351      * @deprecated (4.3) use {@link Builder}.
352      */
353     @Deprecated
354     public void setHeuristicDefaultLifetime(final long heuristicDefaultLifetimeSecs) {
355         this.heuristicDefaultLifetime = heuristicDefaultLifetimeSecs;
356     }
357 
358     /**
359      * Returns whether the cache will behave as a shared cache or not.
360      * @return {@code true} for a shared cache, {@code false} for a non-
361      * shared (private) cache
362      */
363     public boolean isSharedCache() {
364         return isSharedCache;
365     }
366 
367     /**
368      * Sets whether the cache should behave as a shared cache or not.
369      * @param isSharedCache true to behave as a shared cache, false to
370      * behave as a non-shared (private) cache. To have the cache
371      * behave like a browser cache, you want to set this to {@code false}.
372      *
373      * @deprecated (4.3) use {@link Builder}.
374      */
375     @Deprecated
376     public void setSharedCache(final boolean isSharedCache) {
377         this.isSharedCache = isSharedCache;
378     }
379 
380     /**
381      * Returns the maximum number of threads to allow for background
382      * revalidations due to the {@code stale-while-revalidate} directive. A
383      * value of 0 means background revalidations are disabled.
384      */
385     public int getAsynchronousWorkersMax() {
386         return asynchronousWorkersMax;
387     }
388 
389     /**
390      * Sets the maximum number of threads to allow for background
391      * revalidations due to the {@code stale-while-revalidate} directive.
392      * @param max number of threads; a value of 0 disables background
393      * revalidations.
394      *
395      * @deprecated (4.3) use {@link Builder}.
396      */
397     @Deprecated
398     public void setAsynchronousWorkersMax(final int max) {
399         this.asynchronousWorkersMax = max;
400     }
401 
402     /**
403      * Returns the minimum number of threads to keep alive for background
404      * revalidations due to the {@code stale-while-revalidate} directive.
405      */
406     public int getAsynchronousWorkersCore() {
407         return asynchronousWorkersCore;
408     }
409 
410     /**
411      * Sets the minimum number of threads to keep alive for background
412      * revalidations due to the {@code stale-while-revalidate} directive.
413      * @param min should be greater than zero and less than or equal
414      *   to <code>getAsynchronousWorkersMax()</code>
415      *
416      * @deprecated (4.3) use {@link Builder}.
417      */
418     @Deprecated
419     public void setAsynchronousWorkersCore(final int min) {
420         this.asynchronousWorkersCore = min;
421     }
422 
423     /**
424      * Returns the current maximum idle lifetime in seconds for a
425      * background revalidation worker thread. If a worker thread is idle
426      * for this long, and there are more than the core number of worker
427      * threads alive, the worker will be reclaimed.
428      */
429     public int getAsynchronousWorkerIdleLifetimeSecs() {
430         return asynchronousWorkerIdleLifetimeSecs;
431     }
432 
433     /**
434      * Sets the current maximum idle lifetime in seconds for a
435      * background revalidation worker thread. If a worker thread is idle
436      * for this long, and there are more than the core number of worker
437      * threads alive, the worker will be reclaimed.
438      * @param secs idle lifetime in seconds
439      *
440      * @deprecated (4.3) use {@link Builder}.
441      */
442     @Deprecated
443     public void setAsynchronousWorkerIdleLifetimeSecs(final int secs) {
444         this.asynchronousWorkerIdleLifetimeSecs = secs;
445     }
446 
447     /**
448      * Returns the current maximum queue size for background revalidations.
449      */
450     public int getRevalidationQueueSize() {
451         return revalidationQueueSize;
452     }
453 
454     /**
455      * Sets the current maximum queue size for background revalidations.
456      *
457      * @deprecated (4.3) use {@link Builder}.
458      */
459     @Deprecated
460     public void setRevalidationQueueSize(final int size) {
461         this.revalidationQueueSize = size;
462     }
463 
464     @Override
465     protected CacheConfig clone() throws CloneNotSupportedException {
466         return (CacheConfig) super.clone();
467     }
468 
469     public static Builder custom() {
470         return new Builder();
471     }
472 
473     public static Builder copy(final CacheConfig config) {
474         Args.notNull(config, "Cache config");
475         return new Builder()
476             .setMaxObjectSize(config.getMaxObjectSize())
477             .setMaxCacheEntries(config.getMaxCacheEntries())
478             .setMaxUpdateRetries(config.getMaxUpdateRetries())
479             .setHeuristicCachingEnabled(config.isHeuristicCachingEnabled())
480             .setHeuristicCoefficient(config.getHeuristicCoefficient())
481             .setHeuristicDefaultLifetime(config.getHeuristicDefaultLifetime())
482             .setSharedCache(config.isSharedCache())
483             .setAsynchronousWorkersMax(config.getAsynchronousWorkersMax())
484             .setAsynchronousWorkersCore(config.getAsynchronousWorkersCore())
485             .setAsynchronousWorkerIdleLifetimeSecs(config.getAsynchronousWorkerIdleLifetimeSecs())
486             .setRevalidationQueueSize(config.getRevalidationQueueSize())
487             .setNeverCacheHTTP10ResponsesWithQueryString(config.isNeverCacheHTTP10ResponsesWithQuery());
488     }
489 
490 
491     public static class Builder {
492 
493         private long maxObjectSize;
494         private int maxCacheEntries;
495         private int maxUpdateRetries;
496         private boolean heuristicCachingEnabled;
497         private float heuristicCoefficient;
498         private long heuristicDefaultLifetime;
499         private boolean isSharedCache;
500         private int asynchronousWorkersMax;
501         private int asynchronousWorkersCore;
502         private int asynchronousWorkerIdleLifetimeSecs;
503         private int revalidationQueueSize;
504         private boolean neverCacheHTTP10ResponsesWithQuery;
505 
506         Builder() {
507             this.maxObjectSize = DEFAULT_MAX_OBJECT_SIZE_BYTES;
508             this.maxCacheEntries = DEFAULT_MAX_CACHE_ENTRIES;
509             this.maxUpdateRetries = DEFAULT_MAX_UPDATE_RETRIES;
510             this.heuristicCachingEnabled = false;
511             this.heuristicCoefficient = DEFAULT_HEURISTIC_COEFFICIENT;
512             this.heuristicDefaultLifetime = DEFAULT_HEURISTIC_LIFETIME;
513             this.isSharedCache = true;
514             this.asynchronousWorkersMax = DEFAULT_ASYNCHRONOUS_WORKERS_MAX;
515             this.asynchronousWorkersCore = DEFAULT_ASYNCHRONOUS_WORKERS_CORE;
516             this.asynchronousWorkerIdleLifetimeSecs = DEFAULT_ASYNCHRONOUS_WORKER_IDLE_LIFETIME_SECS;
517             this.revalidationQueueSize = DEFAULT_REVALIDATION_QUEUE_SIZE;
518         }
519 
520         /**
521          * Specifies the maximum response body size that will be eligible for caching.
522          * @param maxObjectSize size in bytes
523          */
524         public Builder setMaxObjectSize(final long maxObjectSize) {
525             this.maxObjectSize = maxObjectSize;
526             return this;
527         }
528 
529         /**
530          * Sets the maximum number of cache entries the cache will retain.
531          */
532         public Builder setMaxCacheEntries(final int maxCacheEntries) {
533             this.maxCacheEntries = maxCacheEntries;
534             return this;
535         }
536 
537         /**
538          * Sets the number of times to retry a cache update on failure
539          */
540         public Builder setMaxUpdateRetries(final int maxUpdateRetries) {
541             this.maxUpdateRetries = maxUpdateRetries;
542             return this;
543         }
544 
545         /**
546          * Enables or disables heuristic caching.
547          * @param heuristicCachingEnabled should be {@code true} to
548          *   permit heuristic caching, {@code false} to enable it.
549          */
550         public Builder setHeuristicCachingEnabled(final boolean heuristicCachingEnabled) {
551             this.heuristicCachingEnabled = heuristicCachingEnabled;
552             return this;
553         }
554 
555         /**
556          * Sets coefficient to be used in heuristic freshness caching. This is
557          * interpreted as the fraction of the time between the {@code Last-Modified}
558          * and {@code Date} headers of a cached response during which the cached
559          * response will be considered heuristically fresh.
560          * @param heuristicCoefficient should be between {@code 0.0} and
561          *   {@code 1.0}.
562          */
563         public Builder setHeuristicCoefficient(final float heuristicCoefficient) {
564             this.heuristicCoefficient = heuristicCoefficient;
565             return this;
566         }
567 
568         /**
569          * Sets default lifetime in seconds to be used if heuristic freshness
570          * calculation is not possible. Explicit cache control directives on
571          * either the request or origin response will override this, as will
572          * the heuristic {@code Last-Modified} freshness calculation if it is
573          * available.
574          * @param heuristicDefaultLifetime is the number of seconds to
575          *   consider a cache-eligible response fresh in the absence of other
576          *   information. Set this to {@code 0} to disable this style of
577          *   heuristic caching.
578          */
579         public Builder setHeuristicDefaultLifetime(final long heuristicDefaultLifetime) {
580             this.heuristicDefaultLifetime = heuristicDefaultLifetime;
581             return this;
582         }
583 
584         /**
585          * Sets whether the cache should behave as a shared cache or not.
586          * @param isSharedCache true to behave as a shared cache, false to
587          * behave as a non-shared (private) cache. To have the cache
588          * behave like a browser cache, you want to set this to {@code false}.
589          */
590         public Builder setSharedCache(final boolean isSharedCache) {
591             this.isSharedCache = isSharedCache;
592             return this;
593         }
594 
595         /**
596          * Sets the maximum number of threads to allow for background
597          * revalidations due to the {@code stale-while-revalidate} directive.
598          * @param asynchronousWorkersMax number of threads; a value of 0 disables background
599          * revalidations.
600          */
601         public Builder setAsynchronousWorkersMax(final int asynchronousWorkersMax) {
602             this.asynchronousWorkersMax = asynchronousWorkersMax;
603             return this;
604         }
605 
606         /**
607          * Sets the minimum number of threads to keep alive for background
608          * revalidations due to the {@code stale-while-revalidate} directive.
609          * @param asynchronousWorkersCore should be greater than zero and less than or equal
610          *   to <code>getAsynchronousWorkersMax()</code>
611          */
612         public Builder setAsynchronousWorkersCore(final int asynchronousWorkersCore) {
613             this.asynchronousWorkersCore = asynchronousWorkersCore;
614             return this;
615         }
616 
617         /**
618          * Sets the current maximum idle lifetime in seconds for a
619          * background revalidation worker thread. If a worker thread is idle
620          * for this long, and there are more than the core number of worker
621          * threads alive, the worker will be reclaimed.
622          * @param asynchronousWorkerIdleLifetimeSecs idle lifetime in seconds
623          */
624         public Builder setAsynchronousWorkerIdleLifetimeSecs(final int asynchronousWorkerIdleLifetimeSecs) {
625             this.asynchronousWorkerIdleLifetimeSecs = asynchronousWorkerIdleLifetimeSecs;
626             return this;
627         }
628 
629         /**
630          * Sets the current maximum queue size for background revalidations.
631          */
632         public Builder setRevalidationQueueSize(final int revalidationQueueSize) {
633             this.revalidationQueueSize = revalidationQueueSize;
634             return this;
635         }
636 
637         /**
638          * Sets whether the cache should never cache HTTP 1.0 responses with a query string or not.
639          * @param neverCacheHTTP10ResponsesWithQuery true to never cache responses with a query
640          * string, false to cache if explicit cache headers are found.  Set this to {@code true}
641          * to better emulate IE, which also never caches responses, regardless of what caching
642          * headers may be present.
643          */
644         public Builder setNeverCacheHTTP10ResponsesWithQueryString(
645                 final boolean neverCacheHTTP10ResponsesWithQuery) {
646             this.neverCacheHTTP10ResponsesWithQuery = neverCacheHTTP10ResponsesWithQuery;
647             return this;
648         }
649 
650         public CacheConfig build() {
651             return new CacheConfig(
652                     maxObjectSize,
653                     maxCacheEntries,
654                     maxUpdateRetries,
655                     heuristicCachingEnabled,
656                     heuristicCoefficient,
657                     heuristicDefaultLifetime,
658                     isSharedCache,
659                     asynchronousWorkersMax,
660                     asynchronousWorkersCore,
661                     asynchronousWorkerIdleLifetimeSecs,
662                     revalidationQueueSize,
663                     neverCacheHTTP10ResponsesWithQuery);
664         }
665 
666     }
667 
668     @Override
669     public String toString() {
670         final StringBuilder builder = new StringBuilder();
671         builder.append("[maxObjectSize=").append(this.maxObjectSize)
672                 .append(", maxCacheEntries=").append(this.maxCacheEntries)
673                 .append(", maxUpdateRetries=").append(this.heuristicCachingEnabled)
674                 .append(", heuristicCoefficient=").append(this.heuristicCoefficient)
675                 .append(", heuristicDefaultLifetime=").append(this.heuristicDefaultLifetime)
676                 .append(", isSharedCache=").append(this.isSharedCache)
677                 .append(", asynchronousWorkersMax=").append(this.asynchronousWorkersMax)
678                 .append(", asynchronousWorkersCore=").append(this.asynchronousWorkersCore)
679                 .append(", asynchronousWorkerIdleLifetimeSecs=").append(this.asynchronousWorkerIdleLifetimeSecs)
680                 .append(", revalidationQueueSize=").append(this.revalidationQueueSize)
681                 .append(", neverCacheHTTP10ResponsesWithQuery=").append(this.neverCacheHTTP10ResponsesWithQuery)
682                 .append("]");
683         return builder.toString();
684     }
685 
686 }