Skip to content

Commit

Permalink
final version very broken
Browse files Browse the repository at this point in the history
  • Loading branch information
stumash committed Dec 4, 2018
1 parent ea10465 commit f1596b1
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 48 deletions.
57 changes: 48 additions & 9 deletions src/main/java/group25/Server/Common/AbstractRMHashMapManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

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

private CrashMode crashMode = CrashMode.NO_CRASH;

// TODO: give lock to correct transaction on wakeup from failure
public AbstractRMHashMapManager(String p_name, String filename1, String filename2, String pointerFile, String logFile,
IMiddlewareResourceManager middlewareRM) {
this.m_name = p_name;
Expand All @@ -34,14 +33,38 @@ public AbstractRMHashMapManager(String p_name, String filename1, String filename
this.pointerFile = pointerFile;
this.logFile = logFile;
this.middlewareRM = middlewareRM;

this.currentCommitFile = filename2;
}

public void recover() {
currentCommitFile = xmlPersistor.readObject(pointerFile);
if (currentCommitFile == null) {
currentCommitFile = filename1;
currentCommitFile = filename2; // first commit should be to other file, filename1
globalState = new RMHashMap();
} else {
globalState = xmlPersistor.readObject(currentCommitFile);
}

Integer transactionVotedYes = xmlPersistor.readObject(logFile);
if (transactionVotedYes != null && transactionVotedYes != -1) {
int xid = transactionVotedYes;
String workingFile = currentCommitFile.equals(filename1)? filename2: filename1;
transactionStates.put(xid, xmlPersistor.readObject(workingFile));
globalLock.lock(xid);
try {
if (middlewareRM.commited(xid)) {
System.out.println("middleware says to commit recovered transaction so committing");
doCommit(xid);
} else {
System.out.println("middleware doesn't know about transaction so aborting");
abort(xid);
}
} catch (Exception e) {
System.out.println("Failed to complete recovery on doCommit/abort "+xid);
}
} else {
System.out.println("did not record voting yes");
}
}

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

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

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

// TODO log YES
xmlPersistor.writeObject(xid, logFile);
crashIf(CrashMode.RM_AFTER_DECIDING_VOTE);

// uncertainty phase. Send Yes, and wait for decision
Expand All @@ -107,6 +132,7 @@ public void vote(int xid) throws RemoteException {
System.out.println(GREEN.colorString("Voting yes."));
try {
middlewareRM.receiveVote(xid, true, this.m_name);
xmlPersistor.writeObject(xid, logFile);
crashIf(CrashMode.RM_AFTER_VOTING);
return;
} catch (InvalidTransactionException ite) {
Expand All @@ -121,6 +147,7 @@ public void vote(int xid) throws RemoteException {
try {
System.out.println(GREEN.colorString("Try again to vote yes."));
middlewareRM.receiveVote(xid, true, this.m_name);
xmlPersistor.writeObject(xid, logFile);
crashIf(CrashMode.RM_AFTER_VOTING);
return;
} catch (InvalidTransactionException ite) {
Expand Down Expand Up @@ -154,6 +181,8 @@ public boolean doCommit(int xid) throws RemoteException {
currentCommitFile = filename1;
}

xmlPersistor.writeObject(-1, logFile);

// destroy transaction-specific state
removeTransactionState(xid);

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

public boolean abort(int xid) throws RemoteException {
new Thread(() -> {
xmlPersistor.writeObject(-1, logFile);
System.out.println(m_name + " aborting");
crashIf(CrashMode.RM_AFTER_RECEIVING_DECISION);
if (globalLock.getLockOwner() == xid) {
Expand Down Expand Up @@ -229,7 +259,10 @@ public void updateThenPersistGlobalState(int xid) {
}
}

public RMItem readData(int xid, String key) {
public RMItem readData(int xid, String key) throws UnsupportedOperationException {
if (globalLock.getLockOwner() == xid)
throw new UnsupportedOperationException();

RMHashMap m_data = getTransactionState(xid);
if (m_data == null) {
synchronized(globalState) {
Expand All @@ -249,7 +282,10 @@ public RMItem readData(int xid, String key) {
}

// Writes a data item
public void writeData(int xid, String key, RMItem value) {
public void writeData(int xid, String key, RMItem value) throws UnsupportedOperationException {
if (globalLock.getLockOwner() == xid)
throw new UnsupportedOperationException();

RMHashMap m_data = getTransactionState(xid);
if (m_data == null) {
synchronized(globalState) {
Expand All @@ -272,7 +308,10 @@ public void removeData(int xid, String key) {
}
}

public boolean deleteItem(int xid, String key) {
public boolean deleteItem(int xid, String key) throws UnsupportedOperationException {
if (globalLock.getLockOwner() == xid)
throw new UnsupportedOperationException();

Trace.info("RM::deleteItem(" + xid + ", " + key + ") called");
ReservableItem curObj = (ReservableItem) readData(xid, key);
// Check if there is such an item in the storage
Expand All @@ -292,7 +331,7 @@ public boolean deleteItem(int xid, String key) {
}

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

// Query the price of an item
public int queryPrice(int xid, String key) {
public int queryPrice(int xid, String key) throws UnsupportedOperationException {
Trace.info("RM::queryPrice(" + xid + ", " + key + ") called");
ReservableItem curObj = (ReservableItem) readData(xid, key);
int value = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@ public boolean bundle(int xid, int customerID, Vector<Integer> flightNumbers, St
return true;
}

public boolean commited(int xid) {
return transactionManager.commited(xid);
}

public void receiveVote(int xid, boolean voteYes, String rmName) throws InvalidTransactionException, RemoteException {
transactionManager.receiveVote(xid, voteYes, rmName);
}
Expand Down
56 changes: 26 additions & 30 deletions src/main/java/group25/Server/Common/TransactionManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class TransactionManager implements Remote
private CrashMode crashMode = CrashMode.NO_CRASH;

private HashMap<Integer, ArrayList<Name_RM_Vote>> resourceManagerRecorder = new HashMap<>();
private ArrayList<Integer> commitedTransactions = new ArrayList<>();

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

Expand All @@ -54,6 +55,10 @@ public TransactionManager(
setUpTimeToLiveThread();
}

public boolean commited(int xid) {
return commitedTransactions.contains(xid);
}

public void reconnect(String rmName, String hostname, int port, String objName) throws RemoteException {
switch (rmName) {
case "car": {
Expand Down Expand Up @@ -197,7 +202,7 @@ public synchronized boolean commit(int xid) throws InvalidTransactionException,
}
try {
sem.acquire(); // wait to be awoken by receiveVote()
boolean receivedAllVotes = sem.tryAcquire(25, TimeUnit.SECONDS); // all participants must respond within 25 seconds
boolean receivedAllVotes = sem.tryAcquire(30, TimeUnit.SECONDS); // all participants must respond within 25 seconds
if (!receivedAllVotes) {
System.out.println("Timed out waiting for votes. Aborting");
abort(xid, false);
Expand Down Expand Up @@ -284,6 +289,8 @@ public void receiveVote(int xid, boolean voteYes, String rmName) throws InvalidT
crashIf(CrashMode.TM_BEFORE_SENDING_LAST_DECISION);
}

commitedTransactions.add(xid);

Name_RM_Vote name_rm_vote = resourceManagers.get(i);
try {
name_rm_vote.rm.doCommit(xid);
Expand All @@ -292,8 +299,9 @@ public void receiveVote(int xid, boolean voteYes, String rmName) throws InvalidT
new Thread(() -> {
long startTime = System.currentTimeMillis();
boolean commited = false;
while (System.currentTimeMillis() - startTime < 10 * 1000) {
while (System.currentTimeMillis() - startTime < 30 * 1000) {
try {
name_rm_vote.rm = rmFromRMName(name_rm_vote.rmName);
name_rm_vote.rm.doCommit(xid);
commited = true;
break;
Expand Down Expand Up @@ -364,7 +372,7 @@ public boolean abort(int xid, boolean fromCommit) throws InvalidTransactionExcep
return abort(xid);
} else {
synchronized(transactionAges) {
if (transactionAges.remove(xid) == null) throw new InvalidTransactionException();
if (transactionAges.get(xid) == null) throw new InvalidTransactionException();
}
return abort(xid);
}
Expand Down Expand Up @@ -825,35 +833,23 @@ public boolean shutdownAllResourceManagers(){
}
return true;
}
}

class BeforeImage {
IAbstractRMHashMapManager rm;
String dataKey;
RMItem rItem;

BeforeImage(IAbstractRMHashMapManager rm, String dataKey, RMItem rItem) {
this.rm = rm;
this.dataKey = dataKey;
this.rItem = rItem;
}

void restore(int xid) throws RemoteException {
if (rItem == null) {
rm.removeData(xid, dataKey);
} else {
rm.writeData(xid, dataKey, rItem);
}
}

@Override
public boolean equals(Object other) {
if (!(other instanceof BeforeImage)) {
return false;
private IAbstractRMHashMapManager rmFromRMName(String rmName) {
switch (rmName) {
case "CarSever": {
return carRM;
}
case "RoomServer": {
return roomRM;
}
case "FlightServer": {
return flightRM;
}
case "CustomerServer": {
return customerRM;
}
}
BeforeImage bOther = (BeforeImage) other;
boolean isEqual = bOther.dataKey.equals(this.dataKey);
return isEqual;
return null;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,7 @@ public void crashResourceManager(String rmName, int mode)

public void reconnect(String rmName, String hostname, int port, String objName)
throws RemoteException;

public boolean commited(int xid)
throws RemoteException;
}
7 changes: 5 additions & 2 deletions src/main/java/group25/Server/RMI/RMICarResourceManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class RMICarResourceManager extends CarResourceManager {
private static boolean should_recover = false;

public RMICarResourceManager(String name, IMiddlewareResourceManager midRM) {
super(name, "carData1.xml", "carData2.xml", "carMasterRecord.xml", "carLogFile.txt", midRM);
super(name, "carData1.xml", "carData2.xml", "carMasterRecord.xml", "carLogFile.xml", midRM);
}

public static void main(String args[]) {
Expand Down Expand Up @@ -93,9 +93,12 @@ public static void main(String args[]) {

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

// TODO: recover state
// recover state
if (should_recover) {
server.recover();
System.out.println(BLUE.colorString("recovering state from files"));
} else {
// delete files?
}

// for recovery, force middleware to reconnect to carRM
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class RMICustomerResourceManager extends CustomerResourceManager {
private static boolean should_recover = false;

public RMICustomerResourceManager(String name, IMiddlewareResourceManager midRM) {
super(name, "customerData1.xml", "customerData2.xml", "customerMasterRecord.xml", "customerLogFile.txt", midRM);
super(name, "customerData1.xml", "customerData2.xml", "customerMasterRecord.xml", "customerLogFile.xml", midRM);
}

public static void main(String args[]) {
Expand Down Expand Up @@ -84,9 +84,11 @@ public static void main(String args[]) {
System.setSecurityManager(new SecurityManager());
}

// TODO: recover state
if (should_recover) {
server.recover();
System.out.println(BLUE.colorString("recovering state from files"));
} else {
// delete files?
}

// for recovery, force middleware to reconnect to carRM
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class RMIFlightResourceManager extends FlightResourceManager {
private static boolean should_recover = false;

public RMIFlightResourceManager(String name, IMiddlewareResourceManager midRM) {
super(name, "flightData1.xml", "flightData2.xml", "flightMasterRecord.xml", "flightLogFile.txt", midRM);
super(name, "flightData1.xml", "flightData2.xml", "flightMasterRecord.xml", "flightLogFile.xml", midRM);
}

public static void main(String args[]) {
Expand Down Expand Up @@ -88,9 +88,11 @@ public static void main(String args[]) {
System.setSecurityManager(new SecurityManager());
}

// TODO: recover state
if (should_recover) {
server.recover();
System.out.println(BLUE.colorString("recovering global state from files"));
} else {
// delete files?
}

// for recovery, force middleware to reconnect to carRM
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/group25/Server/RMI/RMIRoomResourceManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class RMIRoomResourceManager extends RoomResourceManager {
private static boolean should_recover = false;

public RMIRoomResourceManager(String name, IMiddlewareResourceManager midRM) {
super(name, "roomData1.xml", "roomData2.xml", "roomMasterRecord.xml", "roomLogFile.txt", midRM);
super(name, "roomData1.xml", "roomData2.xml", "roomMasterRecord.xml", "roomLogFile.xml", midRM);
}

public static void main(String args[]) {
Expand Down Expand Up @@ -85,9 +85,11 @@ public static void main(String args[]) {

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

// TODO: recover state
if (should_recover) {
server.recover();
System.out.println(BLUE.colorString("recovering state from files"));
} else {
// delete files?
}

// for recovery, force middleware to reconnect to carRM
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/group25/Utils/XMLPersistor.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,13 @@ public <T> T readObject(String filepath) {
return null; // file not found
}

return (T)this.xstream.fromXML(str);
T retval = null;
try {
retval = (T) this.xstream.fromXML(str);
} catch (Exception e) {
}

return retval;
}

public ObjectOutputStream getWriteAppendStream(String filepath) {
Expand Down

0 comments on commit f1596b1

Please sign in to comment.