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.
31 public class ProgressMonitorManager
<T
extends IRestServiceProgressMonitor
> {
33 private final Map
<UUID
, T
> monitors
= new ConcurrentHashMap
<UUID
, T
>();
34 private final Map
<UUID
, RemotingProgressMonitorThread
> threads
= new ConcurrentHashMap
<>();
37 private final Map
<UUID
, Long
> timeoutMap
= new HashMap
<UUID
, Long
>();
39 private Thread cleanUpThread
= null;
42 * Time out in minutes for monitors which are done.
43 * A monitor which is set done will be removed after this interval.
45 private final int cleanUpTimeout
= 1;
50 private final int cleanUpInterval
= 1000 * 10; // 10 seconds
52 public ProgressMonitorManager() {
54 this.cleanUpThread
= new Thread(){
61 sleep(cleanUpInterval
);
62 } catch (InterruptedException e
) {
64 System
.err
.println("interrupted");
70 cleanUpThread
.start();
74 * run every n minutes clean up monitors which have been marked done x minutes ago
76 private void scheduledCleanUp() {
78 List
<UUID
> timedOutMonitors
= new ArrayList
<UUID
>();
79 IRestServiceProgressMonitor monitor
;
81 long now
= System
.currentTimeMillis();
82 long nextTimeout
= now
+ cleanUpTimeout
* 1000 * 60;
85 // add monitors which are stopped or done to the timeoutMap
86 for(UUID uuid
: monitors
.keySet()){
87 monitor
= monitors
.get(uuid
);
88 if((monitor
.isFailed() || monitor
.isDone())){
89 if(!timeoutMap
.containsKey(uuid
)){
90 timeoutMap
.put(uuid
, nextTimeout
);
93 if(monitor
.hasFeedbackWaitTimedOut()) {
95 threads
.get(uuid
).interrupt();
99 // check with monitor has timed out
100 for(UUID uuid
: timeoutMap
.keySet()){
101 if(timeoutMap
.get(uuid
) <= now
){
102 timedOutMonitors
.add(uuid
);
106 //finally remove the monitors
107 for(UUID uuid
: timedOutMonitors
){
108 timeoutMap
.remove(uuid
);
109 monitors
.remove(uuid
);
110 threads
.remove(uuid
);
117 * @return the threads
119 public RemotingProgressMonitorThread
getThread(UUID uuid
) {
120 return threads
.get(uuid
);
124 public UUID
registerMonitor(T monitor
, RemotingProgressMonitorThread thread
){
125 UUID uuid
= UUID
.randomUUID();
126 monitors
.put(uuid
, monitor
);
127 threads
.put(uuid
, thread
);
130 public UUID
registerMonitor(T monitor
){
131 UUID uuid
= UUID
.randomUUID();
132 monitors
.put(uuid
, monitor
);
137 public IRestServiceProgressMonitor
getMonitor(UUID uuid
) {
141 return monitors
.get(uuid
);
145 * returns true if the {@link IRestServiceProgressMonitor} identified by the <code>uuid</code>
146 * exists and if it is still indicating a running thread
150 public boolean isMonitorRunning(UUID uuid
) {
151 IRestServiceProgressMonitor monitor
= getMonitor(uuid
);
152 return monitor
!= null && !monitor
.isCanceled() && !monitor
.isDone() && !monitor
.isFailed();
155 public Map
<UUID
, T
> getMonitors() {