/Users/lyon/j4p/src/net/rmi/rmiSynth/HostManager.java

1    package net.rmi.rmiSynth; 
2     
3    // rmi.rmiSynth.HostManager 
4     
5    import java.rmi.AlreadyBoundException; 
6    import java.rmi.RMISecurityManager; 
7    import java.rmi.RemoteException; 
8    import java.rmi.StubNotFoundException; 
9    import java.rmi.registry.LocateRegistry; 
10   import java.rmi.registry.Registry; 
11   import java.util.Enumeration; 
12   import java.util.Vector; 
13    
14   /** 
15    * The <code>HostManager</code> is invoked 
16    * remotely by unicast remote protocol. New 
17    * workers that enter into the grid must know the 
18    * IP address of the HostManager We need to 
19    * provide a leasing mechanism that expires a 
20    * host. First start the host manager. Then start 
21    * the computation servers. Finally start the 
22    * compute client 
23    */ 
24    
25   public class HostManager 
26           extends java.rmi.server.UnicastRemoteObject 
27           implements HostManagerInterface { 
28       // a Multi-cast mechanism is needed to 
29       // obtain the host addBk.address. 
30       // Otherwise it must be hard-coded, like this: 
31    
32       public static final String hostManagerAddress = "192.168.1.96"; 
33       // but some routers do not pass multi-cast packets! 
34       // So the string stays. 
35    
36       private Vector remoteHosts = new Vector(); 
37    
38       private static HostManagerInterface proxy = null; 
39    
40       public Host[] getHosts() 
41               throws RemoteException { 
42           Host h[] = new Host[remoteHosts.size()]; 
43           remoteHosts.copyInto(h); 
44           return h; 
45       } 
46    
47    
48       private HostManager() throws RemoteException { 
49       } 
50    
51    
52       /** 
53        * Use getProxy to gain remote access to the 
54        * host manager. If proxy was already 
55        * obtained, this invocation will not look it 
56        * up again. 
57        */ 
58       public static HostManagerInterface getProxy() { 
59           if (proxy != null) return proxy; 
60           try { 
61               //locate the server class on remote machine 
62               System.out.println( 
63                       "locating remote registry..."); 
64               Registry r = LocateRegistry.getRegistry( 
65                       hostManagerAddress); 
66               System.out.println( 
67                       "looking up Manager..."); 
68               return 
69                       (HostManagerInterface) r.lookup( 
70                               "HostManager"); 
71    
72           } catch (Exception e) { 
73               e.printStackTrace(); 
74           } 
75           return null; 
76    
77       } 
78    
79       public void add(Host h) 
80               throws RemoteException { 
81           if (contains(h)) { 
82               update(h); 
83               return; 
84           } 
85           remoteHosts.addElement(h); 
86           System.out.println("added host:" + h + 
87                              " size=" + 
88                              remoteHosts.size()); 
89       } 
90    
91       public boolean contains(Host h) { 
92           return indexOf(h, 0) >= 0; 
93       } 
94    
95       public synchronized int indexOf(Host h, 
96                                       int index) { 
97           int numberOfHosts = remoteHosts.size(); 
98           if (h == null) { 
99               for (int i = index; i < 
100                                  numberOfHosts; i++) 
101                  if (remoteHosts.elementAt(i) == 
102                      null) 
103                      return i; 
104          } else { 
105              for (int i = index; i < 
106                                  numberOfHosts; i++) 
107                  if (equals(h, 
108                             (Host) remoteHosts.elementAt( 
109                                     i))) 
110                      return i; 
111          } 
112          return -1; 
113      } 
114   
115      // ok, here is a compelling argument for Java generics. 
116      // The Vector code had to be duplicated and strongly 
117      // linked to the Host equals method, or else the WRONG 
118      // equals is used and therefore does not work as expected. 
119      // A discovery. But is it interesting? 
120      // Yes, if it is used in RMI, an equals results in a call-back 
121      // which is not normally needed. The host must register and 
122      // the overhead on this computation is extreme. 
123      public static boolean equals(Host h1, 
124                                   Host h2) { 
125          return h1.getIP().equals(h2.getIP()); 
126      } 
127   
128   
129      private int hostIndex = 0; 
130   
131      /** 
132       * <code>getNextHost</code> returns the next 
133       * host in the list, with wrap-around. 
134       */ 
135      public Host getNextHost() 
136              throws RemoteException { 
137          hostIndex = (hostIndex + 1) % 
138                      remoteHosts.size(); 
139          return (Host) remoteHosts.elementAt( 
140                  hostIndex); 
141   
142      } 
143   
144   
145      public void removeOldHosts() { 
146          for (Enumeration e = remoteHosts.elements(); e.hasMoreElements();) { 
147              Host h = (Host) e.nextElement(); 
148              if (System.currentTimeMillis() - 
149                  h.getTimeOfUpdate() > 
150                  4000) 
151                  remove(h); 
152          } 
153      } 
154   
155      public void remove(Host h) { 
156          int i = indexOf(h, 0); 
157          remoteHosts.remove(i); 
158          System.out.println("HostManager Alert: Host has timed out:" + 
159                             h + 
160                             " and was removed"); 
161      } 
162   
163      public void update(Host h) 
164              throws RemoteException { 
165          System.out.println("update invoked on host manager" + 
166                             new java.util.Date()); 
167          int i = indexOf(h, 0); 
168          h.setTimeOfUpdate( 
169                  System.currentTimeMillis()); 
170          remoteHosts.setElementAt(h, i); 
171   
172      } 
173   
174      public static void main(String args[]) { 
175          try { 
176              startHostManager(); 
177          } catch (StubNotFoundException e) { 
178              System.out.println( 
179                      "ERROR:Did you remember to gui.run RMIC?" 
180                      + 
181                      "\n rmic rmi.rmiSynth.HostManager"); 
182   
183          } catch (RemoteException e) { 
184              e.printStackTrace(); 
185          } 
186   
187      } 
188   
189      /** 
190       * To start the host manager, you must invoke 
191       * the main method. To get an instance of the 
192       * host manager, you must get a proxy. 
193       */ 
194      private static HostManager startHostManager() 
195              throws RemoteException { 
196          // Create and install a security manager 
197          System.setSecurityManager( 
198                  new RMISecurityManager()); 
199          HostManager hm = new HostManager(); 
200          System.out.println( 
201                  "HostManager starting..."); 
202          //Create the registry and bind the Server class to the registry 
203          try { 
204              LocateRegistry.createRegistry(1099); 
205              System.out.println( 
206                      "located registry..."); 
207          } catch (Exception e) { 
208              System.out.println( 
209                      "ERROR:is the registry already on port 1099?"); 
210          } 
211          Registry r = LocateRegistry.getRegistry(); 
212          bindToRegistry(r, hm); 
213          System.out.print( 
214                  "HostManager is running on:"); 
215          try { 
216              System.out.println(Host.getAddress()); 
217          } catch (java.net.UnknownHostException e) { 
218              System.out.println( 
219                      "ERROR:HostManager," 
220                      + 
221                      " can't get local addBk.address?"); 
222          } 
223          return hm; 
224      } 
225   
226      private static void bindToRegistry( 
227              Registry r, HostManager hm) 
228              throws RemoteException { 
229          try { 
230              r.bind("HostManager", hm); 
231          } catch (RemoteException e) { 
232              e.printStackTrace(); 
233          } catch (AlreadyBoundException e) { 
234              System.out.println( 
235                      "HostManager:Rebinding. Was this already running?"); 
236              r.rebind("HostManager", hm); 
237          } 
238      } 
239   
240   
241  } 
242