1 |
package appl.parallel.data; |
2 |
|
3 |
import java.awt.Rectangle; |
4 |
import java.awt.geom.Rectangle2D; |
5 |
import java.io.IOException; |
6 |
import java.io.Serializable; |
7 |
import java.net.InetAddress; |
8 |
import java.net.MalformedURLException; |
9 |
import java.net.UnknownHostException; |
10 |
import java.rmi.Naming; |
11 |
import java.rmi.NotBoundException; |
12 |
import java.rmi.RemoteException; |
13 |
|
14 |
import org.apache.log4j.LogManager; |
15 |
import org.apache.log4j.Logger; |
16 |
|
17 |
import appl.data.LoadingException; |
18 |
import appl.parallel.client.ClientDataServer; |
19 |
import appl.parallel.client.DataServer; |
20 |
import appl.parallel.server.XuluServer; |
21 |
import appl.parallel.spmd.split.DataPartition; |
22 |
|
23 |
import schmitzm.data.WritableGrid; |
24 |
|
25 |
/** |
26 |
* Loads partitioned data from a {@link ClientDataServer}. And unloads the data |
27 |
* |
28 |
* @author Dominik Appl |
29 |
*/ |
30 |
public class XuluClientLoader extends AbstractDataHandler implements |
31 |
PartitionDataHandler { |
32 |
|
33 |
protected InetAddress address; |
34 |
|
35 |
protected String namingString; |
36 |
|
37 |
private String unloadTarget = null; |
38 |
|
39 |
/** |
40 |
* constructs a new {@link XuluClientLoader}. The local IP adress at the |
41 |
* time of construction is later used on serverside for communication (e.g. |
42 |
* unloading). |
43 |
* |
44 |
* @param rootID |
45 |
* the id of the data |
46 |
* @param partitionBounds |
47 |
* the bounds of the partition to be retrieved on server side |
48 |
* @param unloadBounds |
49 |
* the bounds of the partition which is to be uploaded to the |
50 |
* client after calculation |
51 |
*/ |
52 |
public XuluClientLoader(int rootID, ClientDataServer client, |
53 |
Rectangle partitionBounds, Rectangle unloadBounds) { |
54 |
super(rootID, client, partitionBounds, unloadBounds); |
55 |
address = null; |
56 |
namingString = null; |
57 |
try { |
58 |
this.address = InetAddress.getLocalHost(); |
59 |
unloadTarget = address.getHostAddress(); |
60 |
namingString = "rmi://" + unloadTarget + "/DataServer"; |
61 |
} catch (UnknownHostException e) { |
62 |
LOG.error("The client IP could not be determined!!", e); |
63 |
e.printStackTrace(); |
64 |
} |
65 |
} |
66 |
|
67 |
/** |
68 |
* constructs a new {@link XuluClientLoader}. The unloading is done to the |
69 |
* {@link DataServer} at the machine given with the parameter unloadTarget |
70 |
* (IP/Adress or Hostname). |
71 |
* |
72 |
* @param rootID |
73 |
* the id of the data |
74 |
* @param partitionBounds |
75 |
* the bounds of the partition to be retrieved on server side |
76 |
* @param unloadBounds |
77 |
* the bounds of the partition which is to be uploaded to the |
78 |
* client after calculation |
79 |
*/ |
80 |
public XuluClientLoader(int rootID, ClientDataServer client, |
81 |
Rectangle partitionBounds, Rectangle unloadBounds, |
82 |
String unloadTarget) { |
83 |
spmdClient = client; |
84 |
this.unloadTarget = unloadTarget; |
85 |
address = null; |
86 |
namingString = null; |
87 |
try { |
88 |
this.address = InetAddress.getLocalHost(); |
89 |
namingString = "rmi://" + unloadTarget + "/DataServer"; |
90 |
} catch (UnknownHostException e) { |
91 |
LOG.error("The client IP could not be determined!!", e); |
92 |
e.printStackTrace(); |
93 |
} |
94 |
this.rootID = rootID; |
95 |
this.partitionBounds = partitionBounds; |
96 |
this.unloadBounds = unloadBounds; |
97 |
} |
98 |
|
99 |
public XuluClientLoader newInstance(int rootID, ClientDataServer client, |
100 |
Rectangle partitionBounds, Rectangle unloadBounds) { |
101 |
return new XuluClientLoader(rootID, client, partitionBounds, |
102 |
unloadBounds); |
103 |
} |
104 |
|
105 |
/** |
106 |
* Used for deserialization. Do not use for other purposes |
107 |
*/ |
108 |
public XuluClientLoader() { |
109 |
super(); |
110 |
} |
111 |
|
112 |
/* |
113 |
* (non-Javadoc) |
114 |
* |
115 |
* @see appl.data.DataLoader#getLoadInfo() |
116 |
*/ |
117 |
public String getLoadInfo() { |
118 |
return "XuluClientLoader tries to load data with rootID " + rootID |
119 |
+ " from IP: " + address.getHostAddress() + " with naming: " |
120 |
+ namingString; |
121 |
} |
122 |
|
123 |
/* |
124 |
* (non-Javadoc) |
125 |
* |
126 |
* @see appl.data.DataLoader#getLoadInfo() |
127 |
*/ |
128 |
public String getUnloadInfo() { |
129 |
return "XuluClientLoader tries to unload data with rootID " + rootID |
130 |
+ " to IP: " + address.getHostAddress() + " with naming: " |
131 |
+ namingString; |
132 |
} |
133 |
|
134 |
/* |
135 |
* (non-Javadoc) |
136 |
* |
137 |
* @see appl.data.DataLoader#load() |
138 |
*/ |
139 |
public DataPartition load() throws LoadingException { |
140 |
try { |
141 |
LOG.debug(getLoadInfo()); |
142 |
DataServer client = (DataServer) Naming.lookup(namingString); |
143 |
data = client.getPartition(rootID, partitionBounds); |
144 |
LOG.debug("Partition with id " + rootID |
145 |
+ " successfully retrieved from client"); |
146 |
return data; |
147 |
} catch (Exception e) { |
148 |
LOG.error("Partition retrieval failed: " + e.getMessage()); |
149 |
} |
150 |
return null; |
151 |
} |
152 |
|
153 |
/** |
154 |
* Initializes the {@link Logger} after deserialization (used by |
155 |
* {@link java.io.Serializable} |
156 |
* |
157 |
* @author Dominik Appl |
158 |
* @param s |
159 |
* @throws IOException |
160 |
* @see Serializable |
161 |
*/ |
162 |
private synchronized void readObject(java.io.ObjectInputStream s) |
163 |
throws IOException, ClassNotFoundException { |
164 |
// reading standard fields |
165 |
s.defaultReadObject(); |
166 |
// initialize Logger |
167 |
LOG = LogManager.getLogger(this.getClass().getName()); |
168 |
} |
169 |
|
170 |
/* |
171 |
* (non-Javadoc) |
172 |
* |
173 |
* @see appl.data.DataUnloader#unload() |
174 |
*/ |
175 |
public void unload() { |
176 |
try { |
177 |
if (LOG.isDebugEnabled()) |
178 |
LOG.debug(getUnloadInfo()); |
179 |
if (data == null) { |
180 |
if (LOG.isDebugEnabled()) |
181 |
LOG.debug("No data loaded -> nothing to unload"); |
182 |
return; |
183 |
} |
184 |
// construct return grid only if necessary |
185 |
DataPartition returnPartition = null; |
186 |
if (unloadBounds.equals(data.getPartitionBounds())) |
187 |
returnPartition = data; |
188 |
else |
189 |
returnPartition = data.getPartition(unloadBounds); |
190 |
// if there is a local spmdClient try to use it |
191 |
if (spmdClient != null) |
192 |
spmdClient.updatePartition(rootID, returnPartition, |
193 |
unloadBounds); |
194 |
// else connect remotely to client |
195 |
else { |
196 |
DataServer client = (DataServer) Naming.lookup(namingString); |
197 |
client.updatePartition(rootID, returnPartition, unloadBounds); |
198 |
} |
199 |
|
200 |
LOG.debug("Partition with id " + rootID |
201 |
+ " was transfered back to client!"); |
202 |
} catch (Exception e) { |
203 |
LOG.error("Backtransfer of data to client failed!", e); |
204 |
} |
205 |
} |
206 |
|
207 |
} |