ref #7980 reduce minFreeHeap for aggregation
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / ProgressMonitorManager.java
1 /**
2 * Copyright (C) 2015 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.cdm.api.service;
10
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.UUID;
16 import java.util.concurrent.ConcurrentHashMap;
17
18 import org.springframework.stereotype.Component;
19
20 import eu.etaxonomy.cdm.common.monitor.IRestServiceProgressMonitor;
21 import eu.etaxonomy.cdm.common.monitor.RemotingProgressMonitorThread;
22
23 /**
24 * Manages monitors for long running jobs.
25 *
26 * @author cmathew
27 * @since 14 Oct 2015
28 */
29 @Component
30 public class ProgressMonitorManager<T extends IRestServiceProgressMonitor> {
31
32 private final Map<UUID, T> monitors = new ConcurrentHashMap<>();
33 private final Map<UUID, RemotingProgressMonitorThread> threads = new ConcurrentHashMap<>();
34
35
36 private final Map<UUID, Long> timeoutMap = new HashMap<>();
37
38 private Thread cleanUpThread = null;
39
40 /**
41 * Time out in minutes for monitors which are done.
42 * A monitor which is set done will be removed after this interval.
43 */
44 private final int cleanUpTimeout = 1;
45
46 private final int cleanUpInterval = 1000 * 10; // 10 seconds
47
48 public ProgressMonitorManager() {
49
50 this.cleanUpThread = new Thread(){
51
52 @Override
53 public void run() {
54 while(true){
55 scheduledCleanUp();
56 try {
57 sleep(cleanUpInterval);
58 } catch (InterruptedException e) {
59 /* IGNORE */
60 // System.err.println("interrupted");
61 }
62 }
63 }
64
65 };
66 cleanUpThread.start();
67 }
68
69 /**
70 * run every n minutes clean up monitors which have been marked done x minutes ago
71 */
72 private void scheduledCleanUp() {
73
74 List<UUID> timedOutMonitors = new ArrayList<>();
75 IRestServiceProgressMonitor monitor;
76
77 long now = System.currentTimeMillis();
78 long nextTimeout = now + cleanUpTimeout * 1000 * 60;
79
80
81 // add monitors which are stopped or done to the timeoutMap
82 for(UUID uuid : monitors.keySet()){
83 monitor = monitors.get(uuid);
84 if((monitor.isFailed() || monitor.isDone())){
85 if(!timeoutMap.containsKey(uuid)){
86 timeoutMap.put(uuid, nextTimeout);
87 }
88 }
89 if(monitor.hasFeedbackWaitTimedOut()) {
90 monitor.interrupt();
91 threads.get(uuid).interrupt();
92 }
93 }
94
95 // check with monitor has timed out
96 for(UUID uuid : timeoutMap.keySet()){
97 if(timeoutMap.get(uuid) <= now){
98 timedOutMonitors.add(uuid);
99 }
100 }
101
102 //finally remove the monitors
103 for(UUID uuid : timedOutMonitors){
104 releaseMonitor(uuid);
105 }
106 }
107
108 public void releaseMonitor(UUID uuid) {
109 timeoutMap.remove(uuid);
110 monitors.remove(uuid);
111 threads.remove(uuid);
112 }
113
114 public RemotingProgressMonitorThread getThread(UUID uuid) {
115 return threads.get(uuid);
116 }
117
118 public UUID registerMonitor(T monitor, RemotingProgressMonitorThread thread){
119 UUID uuid = UUID.randomUUID();
120 monitors.put(uuid, monitor);
121 threads.put(uuid, thread);
122 return uuid;
123 }
124 public UUID registerMonitor(T monitor){
125 UUID uuid = UUID.randomUUID();
126 monitors.put(uuid, monitor);
127
128 return uuid;
129 }
130
131 public IRestServiceProgressMonitor getMonitor(UUID uuid) {
132 if(uuid == null) {
133 return null;
134 }
135 return monitors.get(uuid);
136 }
137
138 /**
139 * returns true if the {@link IRestServiceProgressMonitor} identified by the <code>uuid</code>
140 * exists and if it is still indicating a running thread
141 * @param uuid
142 * @return
143 */
144 public boolean isMonitorRunning(UUID uuid) {
145 IRestServiceProgressMonitor monitor = getMonitor(uuid);
146 return monitor != null && !monitor.isCanceled() && !monitor.isDone() && !monitor.isFailed();
147 }
148
149 public Map<UUID, T> getMonitors() {
150 return monitors;
151 }
152
153 }