Project

General

Profile

Download (5.92 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.server.instance;
10

    
11
import java.util.HashSet;
12
import java.util.LinkedList;
13
import java.util.Set;
14

    
15
import org.apache.log4j.Logger;
16
import org.eclipse.jetty.util.component.LifeCycle;
17
import org.eclipse.jetty.util.component.LifeCycle.Listener;
18
import org.slf4j.MDC;
19

    
20
import eu.etaxonomy.cdm.server.logging.InstanceLogWrapper;
21

    
22
/**
23
 * @author a.kohlbecker
24
 * @date Jul 29, 2015
25
 *
26
 */
27
public class StartupQueue extends LinkedList<CdmInstance> {
28

    
29
    private static final long serialVersionUID = -8173521573512154767L;
30

    
31
    private final Logger logger = Logger.getLogger(InstanceManager.class);
32

    
33
    Set<CdmInstance> instancesStartingUp = new HashSet<CdmInstance>();
34

    
35
    private int parallelStartUps = 1;
36

    
37
    /**
38
     * @return the parallelStartUps
39
     */
40
    public int getParallelStartUps() {
41
        return parallelStartUps;
42
    }
43

    
44
    /**
45
     * @param parallelStartUps
46
     *            the parallelStartUps to set
47
     */
48
    public void setParallelStartUps(int parallelStartUps) {
49
        this.parallelStartUps = parallelStartUps;
50
    }
51

    
52
    /**
53
     * {@inheritDoc}
54
     */
55
    @Override
56
    public boolean add(CdmInstance e) {
57
        boolean result = super.add(e);
58
        registerAt(e);
59
        return result;
60
    }
61

    
62
    /**
63
     * {@inheritDoc}
64
     */
65
    @Override
66
    public void addFirst(CdmInstance e) {
67
        super.addFirst(e);
68
        registerAt(e);
69
    }
70

    
71
    /**
72
     * {@inheritDoc}
73
     */
74
    @Override
75
    public void addLast(CdmInstance e) {
76
        super.addLast(e);
77
        registerAt(e);
78
    }
79

    
80
    protected void notifyInstanceStartedUp(CdmInstance instance) {
81
        logger.debug("received message that instance " + instance.getName() + " has started up.");
82
        instancesStartingUp.remove(instance);
83
        startNextInstances();
84
    }
85

    
86
    protected void notifyInstanceFailed(CdmInstance instance) {
87
        logger.debug("received message that instance " + instance.getName() + " has failed.");
88
        instancesStartingUp.remove(instance);
89
        startNextInstances();
90
    }
91

    
92
    /**
93
     *
94
     */
95
    private void startNextInstances() {
96
        logger.debug("startNextInstances()");
97
        while(instancesStartingUp.size() < parallelStartUps && !isEmpty()) {
98
            CdmInstance nextInstance = pop();
99
            instancesStartingUp.add(nextInstance);
100
            logger.debug("Starting instance " + nextInstance.getName() + " in new thread.");
101
            Thread t = new StartupThread(nextInstance);
102
            t.start();
103
        }
104
    }
105

    
106
    /**
107
     * @param e
108
     */
109
    @SuppressWarnings("unused")
110
    private void registerAt(CdmInstance e) {
111
        new InstanceListener(e);
112
        startNextInstances();
113

    
114
    }
115

    
116
    class InstanceListener implements Listener {
117

    
118
        private CdmInstance instance;
119

    
120
        InstanceListener(CdmInstance instance) {
121
            this.instance = instance;
122
            instance.getWebAppContext().addLifeCycleListener(this);
123
        }
124

    
125
        /**
126
         * {@inheritDoc}
127
         */
128
        @Override
129
        public void lifeCycleStarting(LifeCycle event) {
130
            // IGNORE
131
        }
132

    
133
        /**
134
         * {@inheritDoc}
135
         */
136
        @Override
137
        public void lifeCycleStarted(LifeCycle event) {
138
            notifyInstanceStartedUp(instance);
139
            // release reference to the instance so
140
            // that the thread can be garbage collected
141
            instance.getWebAppContext().removeLifeCycleListener(this);
142
            instance = null;
143
        }
144

    
145
        /**
146
         * {@inheritDoc}
147
         */
148
        @Override
149
        public void lifeCycleFailure(LifeCycle event, Throwable cause) {
150
            notifyInstanceFailed(instance);
151
            // release reference to the instance so
152
            // that the thread can be garbage collected
153
            instance.getWebAppContext().removeLifeCycleListener(this);
154
            instance = null;
155
        }
156

    
157
        /**
158
         * {@inheritDoc}
159
         */
160
        @Override
161
        public void lifeCycleStopping(LifeCycle event) {
162
            // IGNORE
163
        }
164

    
165
        /**
166
         * {@inheritDoc}
167
         */
168
        @Override
169
        public void lifeCycleStopped(LifeCycle event) {
170
            // IGNORE
171
        }
172

    
173
    }
174

    
175
    class StartupThread extends Thread{
176

    
177
        private final Logger logger = Logger.getLogger(InstanceManager.class);
178

    
179
        private CdmInstance instance;
180

    
181
        StartupThread(CdmInstance instance){
182
            this.instance = instance;
183
        }
184

    
185
        @Override
186
        public void run() {
187
            try {
188
                MDC.put(InstanceLogWrapper.CDM_INSTANCE, instance.getName());
189

    
190
                instance.getWebAppContext().setThrowUnavailableOnStartupException(true);
191
                instance.getWebAppContext().start();
192
                // release reference to the instance so
193
                // that the thread can be garbage collected
194
                instance = null;
195
            } catch(InterruptedException e) {
196
                try {
197
                    instance.getWebAppContext().stop();
198
                } catch (Exception e1) {
199
                    logger.error("Error on stopping instance", e1);
200
                    notifyInstanceFailed(instance);
201
                }
202
            } catch (Throwable e) {
203
                logger.error("Could not start " + instance.getWebAppContext().getContextPath(), e);
204
                instance.getProblems().add(e.getMessage());
205
                instance.setStatus(Status.error);
206
                notifyInstanceFailed(instance);
207
                try {
208
                    // try to stop
209
                    instance.getWebAppContext().stop();
210
                } catch (Exception e1) {
211
                    /* IGNORE */
212
                }
213
            } finally {
214
                MDC.clear();
215
            }
216

    
217
        }
218

    
219
    }
220

    
221
}
(6-6/7)