Project

General

Profile

Download (4.32 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2015 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
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.
8
*/
9
package eu.etaxonomy.cdm.api.service;
10

    
11
import java.util.ArrayList;
12
import java.util.HashMap;
13
import java.util.List;
14
import java.util.Map;
15
import java.util.UUID;
16
import java.util.concurrent.ConcurrentHashMap;
17

    
18
import org.springframework.stereotype.Component;
19

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

    
23
/**
24
 * Manages monitors for long running jobs.
25
 *
26
 * @author cmathew
27
 * @since 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
    private final Map<UUID, RemotingProgressMonitorThread> threads = new ConcurrentHashMap<>();
35

    
36

    
37
    private final Map<UUID, Long> timeoutMap = new HashMap<UUID, Long>();
38

    
39
    private Thread cleanUpThread = null;
40

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

    
47
    /**
48
     *
49
     */
50
    private final int cleanUpInterval = 1000 * 10; // 10 seconds
51

    
52
    public ProgressMonitorManager() {
53

    
54
        this.cleanUpThread = new Thread(){
55

    
56
            @Override
57
            public void run() {
58
                while(true){
59
                    scheduledCleanUp();
60
                    try {
61
                        sleep(cleanUpInterval);
62
                    } catch (InterruptedException e) {
63
                        /* IGNORE */
64
                        System.err.println("interrupted");
65
                    }
66
                }
67
            }
68

    
69
        };
70
        cleanUpThread.start();
71
    }
72

    
73
    /**
74
     * run every n minutes clean up monitors which have been marked done x minutes ago
75
     */
76
    private void scheduledCleanUp() {
77

    
78
        List<UUID> timedOutMonitors = new ArrayList<UUID>();
79
        IRestServiceProgressMonitor monitor;
80

    
81
        long now = System.currentTimeMillis();
82
        long nextTimeout = now + cleanUpTimeout * 1000 * 60;
83

    
84

    
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);
91
                }
92
            }
93
            if(monitor.hasFeedbackWaitTimedOut()) {
94
                monitor.interrupt();
95
                threads.get(uuid).interrupt();
96
            }
97
        }
98

    
99
        // check with monitor has timed out
100
        for(UUID uuid : timeoutMap.keySet()){
101
            if(timeoutMap.get(uuid) <= now){
102
                timedOutMonitors.add(uuid);
103
            }
104
        }
105

    
106
        //finally remove the monitors
107
        for(UUID uuid : timedOutMonitors){
108
            timeoutMap.remove(uuid);
109
            monitors.remove(uuid);
110
            threads.remove(uuid);
111

    
112
        }
113

    
114
    }
115

    
116
    /**
117
     * @return the threads
118
     */
119
    public RemotingProgressMonitorThread getThread(UUID uuid) {
120
        return threads.get(uuid);
121
    }
122

    
123

    
124
    public UUID registerMonitor(T monitor, RemotingProgressMonitorThread thread){
125
        UUID uuid = UUID.randomUUID();
126
        monitors.put(uuid, monitor);
127
        threads.put(uuid, thread);
128
        return uuid;
129
    }
130
    public UUID registerMonitor(T monitor){
131
        UUID uuid = UUID.randomUUID();
132
        monitors.put(uuid, monitor);
133

    
134
        return uuid;
135
    }
136

    
137
    public IRestServiceProgressMonitor getMonitor(UUID uuid) {
138
        if(uuid == null) {
139
            return null;
140
        }
141
        return monitors.get(uuid);
142
    }
143

    
144
    /**
145
     * returns true if the {@link IRestServiceProgressMonitor} identified by the <code>uuid</code>
146
     * exists and if it is still indicating a running thread
147
     * @param uuid
148
     * @return
149
     */
150
    public boolean isMonitorRunning(UUID uuid) {
151
        IRestServiceProgressMonitor monitor = getMonitor(uuid);
152
        return monitor != null && !monitor.isCanceled() && !monitor.isDone() && !monitor.isFailed();
153
    }
154

    
155
    public Map<UUID, T> getMonitors() {
156
        return monitors;
157
    }
158

    
159
}
(87-87/103)