Project

General

Profile

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

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

    
26
    private static final long serialVersionUID = -8173521573512154767L;
27

    
28
    private final Logger logger = Logger.getLogger(InstanceManager.class);
29

    
30
    Set<CdmInstance> instancesStartingUp = new HashSet<CdmInstance>();
31

    
32
    private int parallelStartUps = 1;
33

    
34
    /**
35
     * @return the parallelStartUps
36
     */
37
    public int getParallelStartUps() {
38
        return parallelStartUps;
39
    }
40

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

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

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

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

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

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

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

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

    
111
    }
112

    
113
    class InstanceListener implements Listener {
114

    
115
        private CdmInstance instance;
116

    
117
        InstanceListener(CdmInstance instance) {
118
            this.instance = instance;
119
            instance.getWebAppContext().addLifeCycleListener(this);
120
        }
121

    
122
        /**
123
         * {@inheritDoc}
124
         */
125
        @Override
126
        public void lifeCycleStarting(LifeCycle event) {
127
            // IGNORE
128
        }
129

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

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

    
154
        /**
155
         * {@inheritDoc}
156
         */
157
        @Override
158
        public void lifeCycleStopping(LifeCycle event) {
159
            // IGNORE
160
        }
161

    
162
        /**
163
         * {@inheritDoc}
164
         */
165
        @Override
166
        public void lifeCycleStopped(LifeCycle event) {
167
            // IGNORE
168
        }
169

    
170
    }
171

    
172
    class StartupThread extends Thread{
173

    
174
        private final Logger logger = Logger.getLogger(InstanceManager.class);
175

    
176
        private CdmInstance instance;
177

    
178
        StartupThread(CdmInstance instance){
179
            this.instance = instance;
180
        }
181

    
182
        @Override
183
        public void run() {
184
            try {
185
                instance.getWebAppContext().setThrowUnavailableOnStartupException(true);
186
                instance.getWebAppContext().start();
187
                // release reference to the instance so
188
                // that the thread can be garbage collected
189
                instance = null;
190
            } catch(InterruptedException e) {
191
                try {
192
                    instance.getWebAppContext().stop();
193
                } catch (Exception e1) {
194
                    logger.error("Error on stopping instance", e1);
195
                    notifyInstanceFailed(instance);
196
                }
197
            } catch (Throwable e) {
198
                logger.error("Could not start " + instance.getWebAppContext().getContextPath(), e);
199
                instance.getProblems().add(e.getMessage());
200
                instance.setStatus(Status.error);
201
                notifyInstanceFailed(instance);
202
                try {
203
                    // try to stop
204
                    instance.getWebAppContext().stop();
205
                } catch (Exception e1) {
206
                    /* IGNORE */
207
                }
208
            }
209

    
210
        }
211

    
212
    }
213

    
214
}
(6-6/7)