View Javadoc

1   /*
2    * Copyright (c) 1998-2004 The Jgroup Team.
3    *
4    * This program is free software; you can redistribute it and/or modify
5    * it under the terms of the GNU Lesser General Public License version 2 as
6    * published by the Free Software Foundation.
7    *
8    * This program is distributed in the hope that it will be useful,
9    * but WITHOUT ANY WARRANTY; without even the implied warranty of
10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   * GNU Lesser General Public License for more details.
12   *
13   * You should have received a copy of the GNU Lesser General Public License
14   * along with this program; if not, write to the Free Software
15   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16   *
17   */
18  package jgroup.experiment.runnables;
19  
20  import java.io.IOException;
21  import java.rmi.Remote;
22  import java.rmi.RemoteException;
23  import java.util.HashSet;
24  import java.util.Iterator;
25  import java.util.Set;
26  import java.util.Timer;
27  import java.util.TimerTask;
28  
29  import jgroup.core.ConfigurationException;
30  import jgroup.core.registry.BootstrapRegistry;
31  import jgroup.core.registry.DependableRegistry;
32  import jgroup.core.registry.RegistryFactory;
33  import jgroup.experiment.PropertyDefinition;
34  import jgroup.experiment.Runnable;
35  import jgroup.experiment.ShellCommand;
36  import jgroup.relacs.config.ExperimentConfig;
37  import jgroup.relacs.config.Host;
38  import jgroup.relacs.config.HostSet;
39  import jgroup.test.performance.PerformanceClient;
40  import net.jini.export.Exporter;
41  import net.jini.jeri.BasicILFactory;
42  import net.jini.jeri.BasicJeriExporter;
43  import net.jini.jeri.tcp.TcpServerEndpoint;
44  
45  import org.apache.log4j.Logger;
46  
47  /**
48   * Runnable to deploy clients on the given client host set. 
49   * 
50   * @author Hein Meling
51   * @since Jgroup 2.2
52   */
53  public class DeployClients 
54    implements Runnable, DeployClientCallback
55  {
56  
57    ////////////////////////////////////////////////////////////////////////////////////////////
58    // Logger
59    ////////////////////////////////////////////////////////////////////////////////////////////
60  
61    /** Obtain logger for this class */
62    private static final Logger log = Logger.getLogger(DeployClients.class);
63  
64  
65    ////////////////////////////////////////////////////////////////////////////////////////////
66    // Constants
67    ////////////////////////////////////////////////////////////////////////////////////////////
68  
69    /** The registry name for the deploy clients application */
70    public final String DEPLOY_CLIENTS_REGISTRY_NAME = "Experiment/DeployClients";
71  
72  
73    private boolean calibrated;
74  
75  
76    private Set clientsToCalibrate;
77  
78  
79    ////////////////////////////////////////////////////////////////////////////////////////////
80    // Methods from Runnable
81    ////////////////////////////////////////////////////////////////////////////////////////////
82  
83    /* (non-Javadoc)
84     * @see jgroup.experiment.Runnable#run(jgroup.relacs.config.ExperimentConfig)
85     */
86    public void run(ExperimentConfig ec)
87      throws ConfigurationException 
88    {
89      HostSet clients = ec.getClientConfig().getAllHosts();
90      clientsToCalibrate = new HashSet(clients.size());
91      /** Retrieve the experiment properties */
92      String clientTarget = ec.getProperty(this, "client.target", "perfclient");
93      int clientsPerHost = ec.getIntProperty(this, "clients.per.host", 1);
94      String antCmd = ec.ant(clientTarget, PerformanceClient.properties, this);
95  
96      ThreadGroup threadGroup = new ThreadGroup("DeployClients");
97      int totalNumClients = 0;
98      for (Iterator iter = clients.iterator(); iter.hasNext();) {
99        Host client = (Host) iter.next();
100       String hostName = client.getCanonicalHostName();
101       clientsToCalibrate.add(hostName);
102       StringBuilder sshCmd = new StringBuilder(50);
103       sshCmd.append(ec.ssh(hostName));
104       sshCmd.append(antCmd);
105       for (int i = 0; i < clientsPerHost; i++, totalNumClients++) {
106         try {
107           ShellCommand.exec(sshCmd.toString(), threadGroup);
108         } catch (IOException e) {
109           e.printStackTrace();
110           System.out.println("Could not start clients on " + hostName);
111         }
112       }
113     }
114     ec.set("num.of.clients", Integer.valueOf(totalNumClients));
115 
116     boolean supportCallbacks = ec.getBooleanProperty(this, "supports.rmi.callbacks", false);
117     if (supportCallbacks) {
118       calibrated = false;
119       int calibrationPeriod = ec.getIntProperty(this, "calibration.period", 30);
120       int maxWait = clients.size()*calibrationPeriod;
121       maxWait = ec.getIntProperty(this, "max.waiting.time", maxWait);
122       try {
123         awaitClientCalibration(maxWait);
124       } catch (Exception e) {
125         throw new ConfigurationException("Failed to establish callback environment", e);
126       }
127     }
128   }
129 
130   /* (non-Javadoc)
131    * @see jgroup.experiment.Runnable#getProperties()
132    */
133   public PropertyDefinition[] getProperties()
134   {
135     return null;
136   }
137 
138 
139   ////////////////////////////////////////////////////////////////////////////////////////////
140   // Private Methods
141   ////////////////////////////////////////////////////////////////////////////////////////////
142 
143   private void awaitClientCalibration(int maxWait)
144     throws Exception
145   {
146     /*
147      * Obtain a proxy for the dependable registry running in the
148      * distributed system described in the config.xml file.
149      */
150     DependableRegistry dregistry = RegistryFactory.getRegistry();
151 
152     /*
153      * Export the deploy client callback interface, and bind it
154      * with the local bootstrap registry.
155      */
156     Exporter exporter =
157       new BasicJeriExporter(TcpServerEndpoint.getInstance(0), new BasicILFactory());
158     Remote deployClientProxy = exporter.export(this);
159     BootstrapRegistry.bind(DEPLOY_CLIENTS_REGISTRY_NAME, deployClientProxy);
160 //    BootstrapRegistry.lookup(bootHost, DEPLOY_CLIENTS_REGISTRY_NAME);
161 
162     TimerTask awaitClientCalibration = new TimerTask() {
163       public void run() {
164         log.warn("Not all clients were calibrated; continuing none the less");
165         calibrated = true;
166       }
167     };
168     Timer timer = new Timer("AwaitClientCalibration", true);
169     timer.schedule(awaitClientCalibration, maxWait);
170     log.info("Waiting for all clients to finish calibration");
171     while (!calibrated) {
172       Thread.yield();
173     }
174     timer.cancel();
175     BootstrapRegistry.unbind(DEPLOY_CLIENTS_REGISTRY_NAME);
176     exporter.unexport(true);
177   }
178 
179   /* (non-Javadoc)
180    * @see jgroup.experiment.runnables.DeployClientCallback#calibrated(java.lang.String)
181    */
182   public void calibrated(String host)
183     throws RemoteException
184   {
185     clientsToCalibrate.remove(host);
186     if (clientsToCalibrate.isEmpty()) {
187       calibrated = true;
188     }
189   }
190 
191 } // END DeployClients