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