1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package davmail.http;
21
22 import org.apache.http.conn.HttpClientConnectionManager;
23 import org.apache.log4j.Logger;
24
25 import java.util.HashSet;
26 import java.util.concurrent.Executors;
27 import java.util.concurrent.ScheduledExecutorService;
28 import java.util.concurrent.ThreadFactory;
29 import java.util.concurrent.TimeUnit;
30
31
32
33
34
35 public class DavMailIdleConnectionEvictor {
36 static final Logger LOGGER = Logger.getLogger(DavMailIdleConnectionEvictor.class);
37
38
39 private static final HashSet<HttpClientConnectionManager> connectionManagers = new HashSet<>();
40
41 private static final long sleepTimeMs = 1000L * 60;
42 private static final long maxIdleTimeMs = 1000L * 60 * 5;
43
44 private static ScheduledExecutorService scheduler = null;
45
46 private static void initEvictorThread() {
47 synchronized (connectionManagers) {
48 if (scheduler == null) {
49 scheduler = Executors.newScheduledThreadPool(1, new ThreadFactory() {
50 int count = 0;
51 @Override
52 public Thread newThread(Runnable r) {
53 Thread thread = new Thread(r, "PoolEvictor-" + count++);
54 thread.setDaemon(true);
55 thread.setUncaughtExceptionHandler((t, e) -> LOGGER.error(e.getMessage(), e));
56 return thread;
57 }
58 });
59 scheduler.scheduleAtFixedRate(() -> {
60 synchronized (connectionManagers) {
61
62 for (HttpClientConnectionManager connectionManager : connectionManagers) {
63 connectionManager.closeExpiredConnections();
64 if (maxIdleTimeMs > 0) {
65 connectionManager.closeIdleConnections(maxIdleTimeMs, TimeUnit.MILLISECONDS);
66 }
67 }
68 }
69 }, sleepTimeMs, sleepTimeMs, TimeUnit.MILLISECONDS);
70 }
71 }
72 }
73
74 public static void shutdown() throws InterruptedException {
75 synchronized (connectionManagers) {
76 scheduler.shutdown();
77 if (!scheduler.awaitTermination(sleepTimeMs, TimeUnit.MILLISECONDS)) {
78 LOGGER.warn("Timed out waiting for tasks to complete");
79 }
80 scheduler = null;
81 }
82 }
83
84
85
86
87
88
89 public static void addConnectionManager(HttpClientConnectionManager connectionManager) {
90 synchronized (connectionManagers) {
91 initEvictorThread();
92 connectionManagers.add(connectionManager);
93 }
94 }
95
96
97
98
99
100
101 public static void removeConnectionManager(HttpClientConnectionManager connectionManager) {
102 synchronized (connectionManagers) {
103 connectionManagers.remove(connectionManager);
104 }
105 }
106 }