Project

General

Profile

Download (3.66 KB) Statistics
| Branch: | Tag: | Revision:
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
}
(82-82/97)