Skip to content

Commit f1596b1

Browse files
committed
final version very broken
1 parent ea10465 commit f1596b1

File tree

9 files changed

+105
-48
lines changed

9 files changed

+105
-48
lines changed

src/main/java/group25/Server/Common/AbstractRMHashMapManager.java

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
public abstract class AbstractRMHashMapManager {
1717
private String m_name = "";
18-
protected RMHashMap globalState;
18+
protected RMHashMap globalState = new RMHashMap();
1919
protected HashMap<Integer, RMHashMap> transactionStates = new HashMap<>();
2020
protected XMLPersistor xmlPersistor = new XMLPersistor();
2121
protected final String filename1, filename2, pointerFile, logFile;
@@ -25,7 +25,6 @@ public abstract class AbstractRMHashMapManager {
2525

2626
private CrashMode crashMode = CrashMode.NO_CRASH;
2727

28-
// TODO: give lock to correct transaction on wakeup from failure
2928
public AbstractRMHashMapManager(String p_name, String filename1, String filename2, String pointerFile, String logFile,
3029
IMiddlewareResourceManager middlewareRM) {
3130
this.m_name = p_name;
@@ -34,14 +33,38 @@ public AbstractRMHashMapManager(String p_name, String filename1, String filename
3433
this.pointerFile = pointerFile;
3534
this.logFile = logFile;
3635
this.middlewareRM = middlewareRM;
37-
36+
this.currentCommitFile = filename2;
37+
}
38+
39+
public void recover() {
3840
currentCommitFile = xmlPersistor.readObject(pointerFile);
3941
if (currentCommitFile == null) {
40-
currentCommitFile = filename1;
42+
currentCommitFile = filename2; // first commit should be to other file, filename1
4143
globalState = new RMHashMap();
4244
} else {
4345
globalState = xmlPersistor.readObject(currentCommitFile);
4446
}
47+
48+
Integer transactionVotedYes = xmlPersistor.readObject(logFile);
49+
if (transactionVotedYes != null && transactionVotedYes != -1) {
50+
int xid = transactionVotedYes;
51+
String workingFile = currentCommitFile.equals(filename1)? filename2: filename1;
52+
transactionStates.put(xid, xmlPersistor.readObject(workingFile));
53+
globalLock.lock(xid);
54+
try {
55+
if (middlewareRM.commited(xid)) {
56+
System.out.println("middleware says to commit recovered transaction so committing");
57+
doCommit(xid);
58+
} else {
59+
System.out.println("middleware doesn't know about transaction so aborting");
60+
abort(xid);
61+
}
62+
} catch (Exception e) {
63+
System.out.println("Failed to complete recovery on doCommit/abort "+xid);
64+
}
65+
} else {
66+
System.out.println("did not record voting yes");
67+
}
4568
}
4669

4770
public void crashResourceManager(CrashMode cm) {
@@ -63,6 +86,7 @@ private void crashIf(CrashMode cm) {
6386

6487
public void vote(int xid) throws RemoteException {
6588
System.out.println(getName() + " got vote request.");
89+
xmlPersistor.writeObject(-1, logFile);
6690

6791
// do this all in a new thread since we want vote() to return immediately in the TM
6892
new Thread(() -> {
@@ -99,6 +123,7 @@ public void vote(int xid) throws RemoteException {
99123
updateThenPersistGlobalState(xid);
100124

101125
// TODO log YES
126+
xmlPersistor.writeObject(xid, logFile);
102127
crashIf(CrashMode.RM_AFTER_DECIDING_VOTE);
103128

104129
// uncertainty phase. Send Yes, and wait for decision
@@ -107,6 +132,7 @@ public void vote(int xid) throws RemoteException {
107132
System.out.println(GREEN.colorString("Voting yes."));
108133
try {
109134
middlewareRM.receiveVote(xid, true, this.m_name);
135+
xmlPersistor.writeObject(xid, logFile);
110136
crashIf(CrashMode.RM_AFTER_VOTING);
111137
return;
112138
} catch (InvalidTransactionException ite) {
@@ -121,6 +147,7 @@ public void vote(int xid) throws RemoteException {
121147
try {
122148
System.out.println(GREEN.colorString("Try again to vote yes."));
123149
middlewareRM.receiveVote(xid, true, this.m_name);
150+
xmlPersistor.writeObject(xid, logFile);
124151
crashIf(CrashMode.RM_AFTER_VOTING);
125152
return;
126153
} catch (InvalidTransactionException ite) {
@@ -154,6 +181,8 @@ public boolean doCommit(int xid) throws RemoteException {
154181
currentCommitFile = filename1;
155182
}
156183

184+
xmlPersistor.writeObject(-1, logFile);
185+
157186
// destroy transaction-specific state
158187
removeTransactionState(xid);
159188

@@ -166,6 +195,7 @@ public boolean doCommit(int xid) throws RemoteException {
166195

167196
public boolean abort(int xid) throws RemoteException {
168197
new Thread(() -> {
198+
xmlPersistor.writeObject(-1, logFile);
169199
System.out.println(m_name + " aborting");
170200
crashIf(CrashMode.RM_AFTER_RECEIVING_DECISION);
171201
if (globalLock.getLockOwner() == xid) {
@@ -229,7 +259,10 @@ public void updateThenPersistGlobalState(int xid) {
229259
}
230260
}
231261

232-
public RMItem readData(int xid, String key) {
262+
public RMItem readData(int xid, String key) throws UnsupportedOperationException {
263+
if (globalLock.getLockOwner() == xid)
264+
throw new UnsupportedOperationException();
265+
233266
RMHashMap m_data = getTransactionState(xid);
234267
if (m_data == null) {
235268
synchronized(globalState) {
@@ -249,7 +282,10 @@ public RMItem readData(int xid, String key) {
249282
}
250283

251284
// Writes a data item
252-
public void writeData(int xid, String key, RMItem value) {
285+
public void writeData(int xid, String key, RMItem value) throws UnsupportedOperationException {
286+
if (globalLock.getLockOwner() == xid)
287+
throw new UnsupportedOperationException();
288+
253289
RMHashMap m_data = getTransactionState(xid);
254290
if (m_data == null) {
255291
synchronized(globalState) {
@@ -272,7 +308,10 @@ public void removeData(int xid, String key) {
272308
}
273309
}
274310

275-
public boolean deleteItem(int xid, String key) {
311+
public boolean deleteItem(int xid, String key) throws UnsupportedOperationException {
312+
if (globalLock.getLockOwner() == xid)
313+
throw new UnsupportedOperationException();
314+
276315
Trace.info("RM::deleteItem(" + xid + ", " + key + ") called");
277316
ReservableItem curObj = (ReservableItem) readData(xid, key);
278317
// Check if there is such an item in the storage
@@ -292,7 +331,7 @@ public boolean deleteItem(int xid, String key) {
292331
}
293332

294333
// Query the number of available seats/rooms/cars
295-
public int queryNum(int xid, String key) {
334+
public int queryNum(int xid, String key) throws UnsupportedOperationException {
296335
Trace.info("RM::queryNum(" + xid + ", " + key + ") called");
297336
ReservableItem curObj = (ReservableItem) readData(xid, key);
298337
int value = 0;
@@ -304,7 +343,7 @@ public int queryNum(int xid, String key) {
304343
}
305344

306345
// Query the price of an item
307-
public int queryPrice(int xid, String key) {
346+
public int queryPrice(int xid, String key) throws UnsupportedOperationException {
308347
Trace.info("RM::queryPrice(" + xid + ", " + key + ") called");
309348
ReservableItem curObj = (ReservableItem) readData(xid, key);
310349
int value = 0;

src/main/java/group25/Server/Common/MiddlewareResourceManager.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,10 @@ public boolean bundle(int xid, int customerID, Vector<Integer> flightNumbers, St
188188
return true;
189189
}
190190

191+
public boolean commited(int xid) {
192+
return transactionManager.commited(xid);
193+
}
194+
191195
public void receiveVote(int xid, boolean voteYes, String rmName) throws InvalidTransactionException, RemoteException {
192196
transactionManager.receiveVote(xid, voteYes, rmName);
193197
}

src/main/java/group25/Server/Common/TransactionManager.java

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class TransactionManager implements Remote
3636
private CrashMode crashMode = CrashMode.NO_CRASH;
3737

3838
private HashMap<Integer, ArrayList<Name_RM_Vote>> resourceManagerRecorder = new HashMap<>();
39+
private ArrayList<Integer> commitedTransactions = new ArrayList<>();
3940

4041
private HashMap<Integer, Long> transactionAges = new HashMap<>();
4142

@@ -54,6 +55,10 @@ public TransactionManager(
5455
setUpTimeToLiveThread();
5556
}
5657

58+
public boolean commited(int xid) {
59+
return commitedTransactions.contains(xid);
60+
}
61+
5762
public void reconnect(String rmName, String hostname, int port, String objName) throws RemoteException {
5863
switch (rmName) {
5964
case "car": {
@@ -197,7 +202,7 @@ public synchronized boolean commit(int xid) throws InvalidTransactionException,
197202
}
198203
try {
199204
sem.acquire(); // wait to be awoken by receiveVote()
200-
boolean receivedAllVotes = sem.tryAcquire(25, TimeUnit.SECONDS); // all participants must respond within 25 seconds
205+
boolean receivedAllVotes = sem.tryAcquire(30, TimeUnit.SECONDS); // all participants must respond within 25 seconds
201206
if (!receivedAllVotes) {
202207
System.out.println("Timed out waiting for votes. Aborting");
203208
abort(xid, false);
@@ -284,6 +289,8 @@ public void receiveVote(int xid, boolean voteYes, String rmName) throws InvalidT
284289
crashIf(CrashMode.TM_BEFORE_SENDING_LAST_DECISION);
285290
}
286291

292+
commitedTransactions.add(xid);
293+
287294
Name_RM_Vote name_rm_vote = resourceManagers.get(i);
288295
try {
289296
name_rm_vote.rm.doCommit(xid);
@@ -292,8 +299,9 @@ public void receiveVote(int xid, boolean voteYes, String rmName) throws InvalidT
292299
new Thread(() -> {
293300
long startTime = System.currentTimeMillis();
294301
boolean commited = false;
295-
while (System.currentTimeMillis() - startTime < 10 * 1000) {
302+
while (System.currentTimeMillis() - startTime < 30 * 1000) {
296303
try {
304+
name_rm_vote.rm = rmFromRMName(name_rm_vote.rmName);
297305
name_rm_vote.rm.doCommit(xid);
298306
commited = true;
299307
break;
@@ -364,7 +372,7 @@ public boolean abort(int xid, boolean fromCommit) throws InvalidTransactionExcep
364372
return abort(xid);
365373
} else {
366374
synchronized(transactionAges) {
367-
if (transactionAges.remove(xid) == null) throw new InvalidTransactionException();
375+
if (transactionAges.get(xid) == null) throw new InvalidTransactionException();
368376
}
369377
return abort(xid);
370378
}
@@ -825,35 +833,23 @@ public boolean shutdownAllResourceManagers(){
825833
}
826834
return true;
827835
}
828-
}
829-
830-
class BeforeImage {
831-
IAbstractRMHashMapManager rm;
832-
String dataKey;
833-
RMItem rItem;
834836

835-
BeforeImage(IAbstractRMHashMapManager rm, String dataKey, RMItem rItem) {
836-
this.rm = rm;
837-
this.dataKey = dataKey;
838-
this.rItem = rItem;
839-
}
840-
841-
void restore(int xid) throws RemoteException {
842-
if (rItem == null) {
843-
rm.removeData(xid, dataKey);
844-
} else {
845-
rm.writeData(xid, dataKey, rItem);
846-
}
847-
}
848-
849-
@Override
850-
public boolean equals(Object other) {
851-
if (!(other instanceof BeforeImage)) {
852-
return false;
837+
private IAbstractRMHashMapManager rmFromRMName(String rmName) {
838+
switch (rmName) {
839+
case "CarSever": {
840+
return carRM;
841+
}
842+
case "RoomServer": {
843+
return roomRM;
844+
}
845+
case "FlightServer": {
846+
return flightRM;
847+
}
848+
case "CustomerServer": {
849+
return customerRM;
850+
}
853851
}
854-
BeforeImage bOther = (BeforeImage) other;
855-
boolean isEqual = bOther.dataKey.equals(this.dataKey);
856-
return isEqual;
852+
return null;
857853
}
858854
}
859855

src/main/java/group25/Server/Interface/IMiddlewareResourceManager.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,4 +235,7 @@ public void crashResourceManager(String rmName, int mode)
235235

236236
public void reconnect(String rmName, String hostname, int port, String objName)
237237
throws RemoteException;
238+
239+
public boolean commited(int xid)
240+
throws RemoteException;
238241
}

src/main/java/group25/Server/RMI/RMICarResourceManager.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public class RMICarResourceManager extends CarResourceManager {
3737
private static boolean should_recover = false;
3838

3939
public RMICarResourceManager(String name, IMiddlewareResourceManager midRM) {
40-
super(name, "carData1.xml", "carData2.xml", "carMasterRecord.xml", "carLogFile.txt", midRM);
40+
super(name, "carData1.xml", "carData2.xml", "carMasterRecord.xml", "carLogFile.xml", midRM);
4141
}
4242

4343
public static void main(String args[]) {
@@ -93,9 +93,12 @@ public static void main(String args[]) {
9393

9494
System.out.println("'" + s_serverName + "' resource manager server ready and bound to '" + s_serverName + "'");
9595

96-
// TODO: recover state
96+
// recover state
9797
if (should_recover) {
98+
server.recover();
9899
System.out.println(BLUE.colorString("recovering state from files"));
100+
} else {
101+
// delete files?
99102
}
100103

101104
// for recovery, force middleware to reconnect to carRM

src/main/java/group25/Server/RMI/RMICustomerResourceManager.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class RMICustomerResourceManager extends CustomerResourceManager {
3232
private static boolean should_recover = false;
3333

3434
public RMICustomerResourceManager(String name, IMiddlewareResourceManager midRM) {
35-
super(name, "customerData1.xml", "customerData2.xml", "customerMasterRecord.xml", "customerLogFile.txt", midRM);
35+
super(name, "customerData1.xml", "customerData2.xml", "customerMasterRecord.xml", "customerLogFile.xml", midRM);
3636
}
3737

3838
public static void main(String args[]) {
@@ -84,9 +84,11 @@ public static void main(String args[]) {
8484
System.setSecurityManager(new SecurityManager());
8585
}
8686

87-
// TODO: recover state
8887
if (should_recover) {
88+
server.recover();
8989
System.out.println(BLUE.colorString("recovering state from files"));
90+
} else {
91+
// delete files?
9092
}
9193

9294
// for recovery, force middleware to reconnect to carRM

src/main/java/group25/Server/RMI/RMIFlightResourceManager.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public class RMIFlightResourceManager extends FlightResourceManager {
2929
private static boolean should_recover = false;
3030

3131
public RMIFlightResourceManager(String name, IMiddlewareResourceManager midRM) {
32-
super(name, "flightData1.xml", "flightData2.xml", "flightMasterRecord.xml", "flightLogFile.txt", midRM);
32+
super(name, "flightData1.xml", "flightData2.xml", "flightMasterRecord.xml", "flightLogFile.xml", midRM);
3333
}
3434

3535
public static void main(String args[]) {
@@ -88,9 +88,11 @@ public static void main(String args[]) {
8888
System.setSecurityManager(new SecurityManager());
8989
}
9090

91-
// TODO: recover state
9291
if (should_recover) {
92+
server.recover();
9393
System.out.println(BLUE.colorString("recovering global state from files"));
94+
} else {
95+
// delete files?
9496
}
9597

9698
// for recovery, force middleware to reconnect to carRM

src/main/java/group25/Server/RMI/RMIRoomResourceManager.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public class RMIRoomResourceManager extends RoomResourceManager {
3131
private static boolean should_recover = false;
3232

3333
public RMIRoomResourceManager(String name, IMiddlewareResourceManager midRM) {
34-
super(name, "roomData1.xml", "roomData2.xml", "roomMasterRecord.xml", "roomLogFile.txt", midRM);
34+
super(name, "roomData1.xml", "roomData2.xml", "roomMasterRecord.xml", "roomLogFile.xml", midRM);
3535
}
3636

3737
public static void main(String args[]) {
@@ -85,9 +85,11 @@ public static void main(String args[]) {
8585

8686
System.out.println("'"+s_serverName+"' resource manager server ready and bound to '"+s_serverName+"'");
8787

88-
// TODO: recover state
8988
if (should_recover) {
89+
server.recover();
9090
System.out.println(BLUE.colorString("recovering state from files"));
91+
} else {
92+
// delete files?
9193
}
9294

9395
// for recovery, force middleware to reconnect to carRM

src/main/java/group25/Utils/XMLPersistor.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,13 @@ public <T> T readObject(String filepath) {
8080
return null; // file not found
8181
}
8282

83-
return (T)this.xstream.fromXML(str);
83+
T retval = null;
84+
try {
85+
retval = (T) this.xstream.fromXML(str);
86+
} catch (Exception e) {
87+
}
88+
89+
return retval;
8490
}
8591

8692
public ObjectOutputStream getWriteAppendStream(String filepath) {

0 commit comments

Comments
 (0)