2 * Copyright (C) 2015 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
9 package eu
.etaxonomy
.cdm
.api
.service
;
11 import java
.util
.ArrayList
;
12 import java
.util
.HashMap
;
13 import java
.util
.List
;
15 import java
.util
.UUID
;
16 import java
.util
.concurrent
.ConcurrentHashMap
;
18 import org
.springframework
.stereotype
.Component
;
20 import eu
.etaxonomy
.cdm
.common
.monitor
.IRestServiceProgressMonitor
;
21 import eu
.etaxonomy
.cdm
.common
.monitor
.RemotingProgressMonitorThread
;
24 * Manages monitors for long running jobs.
30 public class ProgressMonitorManager
<T
extends IRestServiceProgressMonitor
> {
32 private final Map
<UUID
, T
> monitors
= new ConcurrentHashMap
<>();
33 private final Map
<UUID
, RemotingProgressMonitorThread
> threads
= new ConcurrentHashMap
<>();
36 private final Map
<UUID
, Long
> timeoutMap
= new HashMap
<>();
38 private Thread cleanUpThread
= null;
41 * Time out in minutes for monitors which are done.
42 * A monitor which is set done will be removed after this interval.
44 private final int cleanUpTimeout
= 1;
46 private final int cleanUpInterval
= 1000 * 10; // 10 seconds
48 public ProgressMonitorManager() {
50 this.cleanUpThread
= new Thread(){
57 sleep(cleanUpInterval
);
58 } catch (InterruptedException e
) {
60 // System.err.println("interrupted");
66 cleanUpThread
.start();
70 * run every n minutes clean up monitors which have been marked done x minutes ago
72 private void scheduledCleanUp() {
74 List
<UUID
> timedOutMonitors
= new ArrayList
<>();
75 IRestServiceProgressMonitor monitor
;
77 long now
= System
.currentTimeMillis();
78 long nextTimeout
= now
+ cleanUpTimeout
* 1000 * 60;
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
);
89 if(monitor
.hasFeedbackWaitTimedOut()) {
91 threads
.get(uuid
).interrupt();
95 // check with monitor has timed out
96 for(UUID uuid
: timeoutMap
.keySet()){
97 if(timeoutMap
.get(uuid
) <= now
){
98 timedOutMonitors
.add(uuid
);
102 //finally remove the monitors
103 for(UUID uuid
: timedOutMonitors
){
104 releaseMonitor(uuid
);
108 public void releaseMonitor(UUID uuid
) {
109 timeoutMap
.remove(uuid
);
110 monitors
.remove(uuid
);
111 threads
.remove(uuid
);
114 public RemotingProgressMonitorThread
getThread(UUID uuid
) {
115 return threads
.get(uuid
);
118 public UUID
registerMonitor(T monitor
, RemotingProgressMonitorThread thread
){
119 UUID uuid
= UUID
.randomUUID();
120 monitors
.put(uuid
, monitor
);
121 threads
.put(uuid
, thread
);
124 public UUID
registerMonitor(T monitor
){
125 UUID uuid
= UUID
.randomUUID();
126 monitors
.put(uuid
, monitor
);
131 public IRestServiceProgressMonitor
getMonitor(UUID uuid
) {
135 return monitors
.get(uuid
);
139 * returns true if the {@link IRestServiceProgressMonitor} identified by the <code>uuid</code>
140 * exists and if it is still indicating a running thread
144 public boolean isMonitorRunning(UUID uuid
) {
145 IRestServiceProgressMonitor monitor
= getMonitor(uuid
);
146 return monitor
!= null && !monitor
.isCanceled() && !monitor
.isDone() && !monitor
.isFailed();
149 public Map
<UUID
, T
> getMonitors() {