Project

General

Profile

Download (4.3 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
@Component
30
public class ProgressMonitorManager<T extends IRestServiceProgressMonitor> {
31

    
32
    private final Map<UUID, T> monitors = new ConcurrentHashMap<>();
33
    private final Map<UUID, RemotingProgressMonitorThread> threads = new ConcurrentHashMap<>();
34

    
35

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

    
38
    private Thread cleanUpThread = null;
39

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

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

    
48
    public ProgressMonitorManager() {
49

    
50
        this.cleanUpThread = new Thread(){
51

    
52
            @Override
53
            public void run() {
54
                while(true){
55
                    scheduledCleanUp();
56
                    try {
57
                        sleep(cleanUpInterval);
58
                    } catch (InterruptedException e) {
59
                        /* IGNORE */
60
//                       System.err.println("interrupted");
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<>();
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
            if(monitor.hasFeedbackWaitTimedOut()) {
90
                monitor.interrupt();
91
                threads.get(uuid).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
            releaseMonitor(uuid);
105
        }
106
    }
107

    
108
    public void releaseMonitor(UUID uuid) {
109
        timeoutMap.remove(uuid);
110
        monitors.remove(uuid);
111
        threads.remove(uuid);
112
    }
113

    
114
    public RemotingProgressMonitorThread getThread(UUID uuid) {
115
        return threads.get(uuid);
116
    }
117

    
118
    public UUID registerMonitor(T monitor, RemotingProgressMonitorThread thread){
119
        UUID uuid = UUID.randomUUID();
120
        monitors.put(uuid, monitor);
121
        threads.put(uuid, thread);
122
        return uuid;
123
    }
124
    public UUID registerMonitor(T monitor){
125
        UUID uuid = UUID.randomUUID();
126
        monitors.put(uuid, monitor);
127

    
128
        return uuid;
129
    }
130

    
131
    public IRestServiceProgressMonitor getMonitor(UUID uuid) {
132
        if(uuid == null) {
133
            return null;
134
        }
135
        return monitors.get(uuid);
136
    }
137

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

    
149
    public Map<UUID, T> getMonitors() {
150
        return monitors;
151
    }
152

    
153
}
(76-76/95)