Project

General

Profile

Download (3.44 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

    
18
import org.springframework.stereotype.Component;
19

    
20
import eu.etaxonomy.cdm.common.monitor.IRestServiceProgressMonitor;
21

    
22
/**
23
 * Manages monitors for long running jobs.
24
 *
25
 * @author cmathew
26
 * @date 14 Oct 2015
27
 *
28
 */
29
@Component
30
public class ProgressMonitorManager<T extends IRestServiceProgressMonitor> {
31

    
32
    private final Map<UUID, T> monitors = new HashMap<UUID, T>();
33

    
34
    private final Map<UUID, Long> timeoutMap = new HashMap<UUID, Long>();
35

    
36
    private Thread cleanUpThread = null;
37

    
38
    /**
39
     * Time out in minutes for monitors which are done.
40
     * A monitor which is set done will be removed after this interval.
41
     */
42
    private final int cleanUpTimeout = 1;
43

    
44
    /**
45
     *
46
     */
47
    private final int cleanUpInterval = 1000 * 10; // 10 seconds
48

    
49
    public ProgressMonitorManager() {
50

    
51
        this.cleanUpThread = new Thread(){
52

    
53
            @Override
54
            public void run() {
55
                while(true){
56
                    scheduledCleanUp();
57
                    try {
58
                        sleep(cleanUpInterval);
59
                    } catch (InterruptedException e) {
60
                        /* IGNORE */
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<UUID>();
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
        }
90

    
91
        // check with monitor has timed out
92
        for(UUID uuid : timeoutMap.keySet()){
93
            if(timeoutMap.get(uuid) <= now){
94
                timedOutMonitors.add(uuid);
95
            }
96
        }
97

    
98
        //finally remove the monitors
99
        for(UUID uuid : timedOutMonitors){
100
            timeoutMap.remove(uuid);
101
            monitors.remove(uuid);
102
        }
103

    
104
    }
105

    
106
    public UUID registerMonitor(T monitor){
107
        UUID uuid = UUID.randomUUID();
108
        monitors.put(uuid, monitor);
109
        return uuid;
110
    }
111

    
112
    public IRestServiceProgressMonitor getMonitor(UUID uuid) {
113
        return monitors.get(uuid);
114
    }
115

    
116
    /**
117
     * returns true if the {@link IRestServiceProgressMonitor} identified by the <code>uuid</code>
118
     * exists and if it is still indicating a running thread
119
     * @param uuid
120
     * @return
121
     */
122
    public boolean isMonitorRunning(UUID uuid) {
123
        IRestServiceProgressMonitor monitor = getMonitor(uuid);
124
        return monitor != null && !monitor.isCanceled() && !monitor.isDone() && !monitor.isFailed();
125
    }
126

    
127
    public Map<UUID, T> getMonitors() {
128
        return monitors;
129
    }
130

    
131
}
(80-80/95)