KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > simulator > container > Container


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.simulator.container;
5
6 import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean;
7
8 import com.tc.simulator.app.Application;
9 import com.tc.simulator.app.ApplicationBuilder;
10 import com.tc.simulator.app.ApplicationInstantiationException;
11 import com.tc.simulator.app.ErrorContext;
12 import com.tc.simulator.app.GlobalIdGenerator;
13 import com.tc.simulator.control.Control;
14 import com.tc.simulator.control.TCBrokenBarrierException;
15 import com.tc.simulator.listener.OutputListener;
16 import com.tc.simulator.listener.ResultsListener;
17 import com.tc.simulator.listener.StatsListenerFactory;
18 import com.tc.util.Assert;
19 import com.tc.util.TCTimeoutException;
20 import com.tcsimulator.ControlImpl;
21 import com.tcsimulator.listener.ApplicationListenerProvider;
22
23 import java.util.ArrayList JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26
27 public final class Container implements Runnable JavaDoc {
28
29   private final ContainerConfig config;
30   private final ContainerState containerState;
31   private final GlobalIdGenerator idGenerator;
32   private final Control control;
33   private final ResultsListener resultsListener;
34   private final ApplicationBuilder applicationBuilder;
35   private final String JavaDoc globalId;
36
37   public Container(ContainerConfig config, ContainerStateFactory containerStateFactory, GlobalIdGenerator idGenerator,
38                    Control control, ResultsListener resultsListener, ApplicationBuilder applicationBuilder) {
39     this.config = config;
40     this.idGenerator = idGenerator;
41     this.control = control;
42     this.resultsListener = resultsListener;
43     this.applicationBuilder = applicationBuilder;
44     this.globalId = this.idGenerator.nextId() + "";
45
46     this.containerState = containerStateFactory.newContainerState(this.globalId);
47     Assert.assertNoNullElements(new Object JavaDoc[] { this.config, this.idGenerator, this.control, this.resultsListener,
48         this.applicationBuilder });
49   }
50
51   /**
52    * Make applications go.
53    */

54   public synchronized void run() {
55     Thread.currentThread().setContextClassLoader(applicationBuilder.getContextClassLoader());
56
57     SynchronizedBoolean isRunning = new SynchronizedBoolean(true);
58     try {
59       if (!validateConfig()) return;
60       if (!waitForStart()) return;
61       Control applicationControl = new ControlImpl(this.config.getApplicationInstanceCount(), this.config
62           .getApplicationInstanceCount());
63       ContainerExecutionInstance containerExecution = new ContainerExecutionInstance();
64
65       startInstances(containerExecution, applicationControl);
66
67       if (!waitForAllComplete(applicationControl)) return;
68       notifyResult(containerExecution);
69     } catch (Throwable JavaDoc t) {
70       notifyError("Unexpected error executing application.", t);
71     } finally {
72       isRunning.set(false);
73       this.control.notifyComplete();
74       try {
75         this.control.waitForAllComplete(this.config.getApplicationExecutionTimeout());
76       } catch (InterruptedException JavaDoc e) {
77         e.printStackTrace();
78       }
79     }
80   }
81
82   private boolean validateConfig() {
83     if (this.config.getContainerStartTimeout() < 1) {
84       notifyError(new ContainerConfigException("Container start timeout must be greater than zero.",
85                                                ContainerConfigException.INVALID_CONTAINER_START_TIMEOUT));
86       return false;
87     }
88     if (this.config.getApplicationStartTimeout() < 1) {
89       notifyError(new ContainerConfigException("Application start timeout must be greater than zero.",
90                                                ContainerConfigException.INVALID_APPLICATION_START_TIMEOUT));
91       return false;
92     }
93     if (this.config.getApplicationExecutionTimeout() == 0) {
94       notifyError(new ContainerConfigException("Application execution timeout must be greater than or less than zero.",
95                                                ContainerConfigException.INVALID_APPLICATION_EXECUTION_TIMEOUT));
96       return false;
97     }
98     if (this.config.getApplicationInstanceCount() < 1) {
99       notifyError(new ContainerConfigException("Application instance count must be greater than zero.",
100                                                ContainerConfigException.INVALID_APPLICATION_INSTANCE_COUNT));
101       return false;
102     }
103     return true;
104   }
105
106   private boolean waitForStart() throws TCBrokenBarrierException, InterruptedException JavaDoc {
107     boolean rv = false;
108     try {
109       println("Waiting for all containers to start...");
110       this.control.waitForStart(this.config.getContainerStartTimeout());
111       rv = true;
112     } catch (TCTimeoutException e) {
113       rv = false;
114       this.resultsListener.notifyStartTimeout();
115       notifyFailure();
116     }
117     println("Done waiting for all containers to start.");
118     return rv;
119   }
120
121   /*********************************************************************************************************************
122    * Private stuff
123    */

124
125   private ApplicationExecutionInstance newExecutionInstance(ContainerExecutionInstance containerExecution,
126                                                             Control applicationControl)
127       throws ApplicationInstantiationException {
128     String JavaDoc appId = this.idGenerator.nextId() + "";
129     System.err.println("Creating new execution instance: " + appId);
130     OutputListener outputListener = this.containerState.newOutputListener();
131     ApplicationExecutionInstance executionInstance = new ApplicationExecutionInstance(containerExecution,
132                                                                                       applicationControl, this.containerState);
133
134     ApplicationListenerProvider appListeners = new ApplicationListenerProvider(outputListener, executionInstance,
135                                                                                this.containerState);
136     Application application = applicationBuilder.newApplication(appId, appListeners);
137     executionInstance.setApplication(application);
138
139     return executionInstance;
140   }
141
142   private void println(String JavaDoc msg) {
143     System.out.println("Container: " + msg);
144   }
145
146   private void startInstances(ContainerExecutionInstance containerExecution, Control applicationControl)
147       throws ApplicationInstantiationException {
148     println("Starting application execution...");
149     for (int i = 0; i < config.getApplicationInstanceCount(); i++) {
150       println("exeution " + (i + 1) + " of " + config.getApplicationInstanceCount());
151       ApplicationExecutionInstance executionInstance = newExecutionInstance(containerExecution, applicationControl);
152       containerExecution.addExecution(executionInstance);
153       executionInstance.start();
154     }
155     println("All application executions are started.");
156   }
157
158   private boolean waitForAllComplete(Control applicationControl) throws InterruptedException JavaDoc {
159     println("Waiting for all containers to complete. Timeout: " + config.getApplicationExecutionTimeout());
160     if (!applicationControl.waitForAllComplete(config.getApplicationExecutionTimeout())) {
161       resultsListener.notifyExecutionTimeout();
162       notifyFailure();
163       println("Application execution timed out.");
164       return false;
165     }
166     println("Application execution completed.");
167     return true;
168   }
169
170   private void notifyError(Throwable JavaDoc t) {
171     notifyError("", t);
172   }
173
174   private void notifyError(String JavaDoc message, Throwable JavaDoc t) {
175     notifyError(new ErrorContext(message, t));
176   }
177
178   private void notifyError(ErrorContext ctxt) {
179     ctxt.dump(System.err);
180     this.resultsListener.notifyError(ctxt);
181     notifyFailure();
182   }
183
184   private void notifyFailure() {
185     System.err.println(Thread.currentThread() + ": failure");
186     Thread.dumpStack();
187     this.resultsListener.notifyResult(new ContainerResult());
188   }
189
190   private void notifyResult(ContainerExecutionInstance containerExecution) {
191     this.resultsListener.notifyResult(new ContainerResult(containerExecution));
192   }
193
194   private ApplicationRunner newApplicationRunner(Control applicationControl, ResultsListener appRunnerResultsListener,
195                                                  Application application, StatsListenerFactory statsListenerFactory) {
196
197     ApplicationRunnerConfig exeConfig = new ApplicationRunnerConfig() {
198       public long getStartTimeout() {
199         return config.getApplicationStartTimeout();
200       }
201     };
202
203     ApplicationRunner runner = new ApplicationRunner(exeConfig, applicationControl, appRunnerResultsListener,
204                                                      application, statsListenerFactory);
205
206     return runner;
207   }
208
209   /*********************************************************************************************************************
210    * Helper classes.
211    */

212
213   static final class ContainerExecutionInstance {
214     private final List JavaDoc executions = new ArrayList JavaDoc();
215     private boolean applicationStartTimeout = false;
216     private boolean applicationExecutionTimeout = false;
217
218     synchronized void addExecution(ApplicationExecutionInstance execution) {
219       this.executions.add(execution);
220     }
221
222     synchronized int getExecutionCount() {
223       return this.executions.size();
224     }
225
226     synchronized void notifyApplicationStartTimeout() {
227       this.applicationStartTimeout = true;
228     }
229
230     synchronized void notifyApplicationExecutionTimeout() {
231       this.applicationExecutionTimeout = true;
232     }
233
234     private synchronized boolean compileResults() {
235       boolean result = true;
236       for (Iterator JavaDoc i = executions.iterator(); i.hasNext();) {
237         ApplicationExecutionInstance execution = (ApplicationExecutionInstance) i.next();
238         if (!execution.application.interpretResult(execution.result)) result = false;
239       }
240       return result;
241     }
242
243     synchronized boolean getResult() {
244       boolean compiledResults = compileResults();
245       System.err.println("start timeout: " + this.applicationStartTimeout);
246       System.err.println("execution timeout: " + this.applicationExecutionTimeout);
247       System.err.println("compiled results: " + compiledResults);
248       return !this.applicationStartTimeout && !this.applicationExecutionTimeout && compiledResults;
249     }
250   }
251
252   final class ApplicationExecutionInstance implements ResultsListener {
253     private final ContainerExecutionInstance containerExecution;
254     private final Control applicationControl;
255     private Application application;
256     private Object JavaDoc result;
257     private final StatsListenerFactory statsListenerFactory;
258
259     ApplicationExecutionInstance(ContainerExecutionInstance containerExecution, Control control,
260                                  StatsListenerFactory statsListenerFactory) {
261       this.containerExecution = containerExecution;
262       this.applicationControl = control;
263       this.statsListenerFactory = statsListenerFactory;
264     }
265
266     void setApplication(Application app) {
267       this.application = app;
268     }
269
270     void start() {
271       ApplicationRunner runner = newApplicationRunner(applicationControl, this, this.application, this.statsListenerFactory);
272
273       ClassLoader JavaDoc loader = application.getClass().getClassLoader();
274       Thread JavaDoc thread = new Thread JavaDoc(runner);
275       thread.setContextClassLoader(loader);
276       thread.start();
277     }
278
279     Application getApplication() {
280       return this.application;
281     }
282
283     public void setGlobalId(long globalId) {
284       return;
285     }
286
287     public void notifyStartTimeout() {
288       this.containerExecution.notifyApplicationStartTimeout();
289     }
290
291     public void notifyExecutionTimeout() {
292       this.containerExecution.notifyApplicationExecutionTimeout();
293     }
294
295     public void notifyError(ErrorContext ectxt) {
296       Container.this.notifyError(ectxt);
297     }
298
299     public void notifyResult(Object JavaDoc theResult) {
300       this.result = theResult;
301     }
302
303     Object JavaDoc getResult() {
304       return this.result;
305     }
306
307   }
308
309 }
Popular Tags