changeset 395:a2efdec5cbfc

insert_ack/delete_ack protocol all written.
author one
date Wed, 19 Nov 2008 16:41:09 +0900
parents 1d5b608f39da
children dc616339b00a
files rep/handler/Editor.java test/sematest/TestEditor.java
diffstat 2 files changed, 32 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/rep/handler/Editor.java	Wed Nov 19 15:31:29 2008 +0900
+++ b/rep/handler/Editor.java	Wed Nov 19 16:41:09 2008 +0900
@@ -20,6 +20,7 @@
 	private List<REPCommand> sentList = new LinkedList<REPCommand>();
 	private REPCommand quit2=null;
 	private boolean merging;
+	private REPCommand preMergeCommand;
 	public static boolean noMergeMode=false;
 	static final boolean doOptimize = true;
 
@@ -67,11 +68,17 @@
 			if (manager.hasWaitingCommand(channel)) {
 				// We cannot do this operation before watingCommandQueue.
 				manager.addWaitingCommand(new PacketSet(channel, this, command));
-				return;
 			} else if (isMerging()) { 
 				manager.addWaitingCommand(new PacketSet(getChannel(), this, new REPCommand(command)));
 			} else {
-				translator.transReceiveCmd(next,command);
+				switch(command.cmd) {
+				case REPCMD_INSERT_ACK:
+				case REPCMD_DELETE_ACK:
+					startMerge(command);
+					break;
+				default:
+					translator.transReceiveCmd(next,command);
+				}
 			}
 		}
 		return;
@@ -94,12 +101,30 @@
 			ServerMainLoop.logger.writeLog(err);
 			assert(false);
 		}
+		switch (command.cmd) {
+		case REPCMD_INSERT_ACK:
+		case REPCMD_DELETE_ACK:
+			// Second Phase が終わって同期が終了。
+			return;
+		case REPCMD_INSERT:
+			command.cmd = REP.REPCMD_INSERT_ACK;
+			break;
+		case REPCMD_DELETE:
+			command.cmd = REP.REPCMD_DELETE_ACK;
+			break;
+		}
+		startMerge(command);
+		return;
+	}
 
+	private void startMerge(REPCommand command) {
+		preMergeCommand = command;
 		// merge は必須だが、EditorのCommand実装をテストするには邪魔なので、off に出来るようにする。
 		if (noMergeMode) {
-			// END_MERGE を出さないと、EditorがprevSeqをreset出来ない。
 			REPCommand ack = new REPCommand(REP.SMCMD_END_MERGE,command.sid,REP.SM_EID.id,seq(),0,"");
 			send(ack);
+			// END_MERGE_ACK が返って来てから、送る方が正しいような気もするが...
+			next.send(preMergeCommand);
 			return;
 		}
 		// START_MERGE を送る
@@ -111,7 +136,6 @@
 		// 入力を止めて、merge にそなえる。merge は、eidtor 側から
 		// ACKが来てから始まる。
 		translator.startMerge(cmd);
-		return;
 	}
 
 	@Override
@@ -144,6 +168,8 @@
 			if(translator.isMerging()) return;
 			REPCommand mergeEnd = new REPCommand(REP.SMCMD_END_MERGE,sid,eid,seq(),0,"");
 			send(mergeEnd);
+			// send INSERT_ACK/DELETE_ACK as next editor's merge trigger
+			next.send(preMergeCommand);
 			merging = false;
 		}
 		if (quit2!=null) checkQuit();
--- a/test/sematest/TestEditor.java	Wed Nov 19 15:31:29 2008 +0900
+++ b/test/sematest/TestEditor.java	Wed Nov 19 16:41:09 2008 +0900
@@ -26,7 +26,6 @@
 	private InetSocketAddress semaIP;
 	private REPLogger ns;
 	private int seq = 0;
-	private int prevSeq = 0;
 	public Text text;
 	public LinkedList<REPCommand> cmds;
 	private int eid = 0;
@@ -188,7 +187,6 @@
 			case SMCMD_JOIN:
 			case SMCMD_PUT:
 				sendCommand(cmd);
-				prevSeq = seq;
 				/*
 				 * To prevent confusion, stop user input until the ack
 				 */
@@ -231,8 +229,6 @@
 		switch(cmd.cmd) {
 		case REPCMD_INSERT	:
 			text.insert(cmd.lineno, cmd.string);
-			if (cmd.eid!=REP.MERGE_EID.id) 
-				addNop();
 			forwardCommand(cmd);
 			break;
 		case REPCMD_DELETE	:
@@ -240,14 +236,12 @@
 			if(cmd.lineno>text.size()) {
 				del = text.delete(cmd.lineno);
 			}
-			if (cmd.eid!=REP.MERGE_EID.id) 
-				addNop();
 			cmd.setString(del);
 			forwardCommand(cmd);
 			break;
 		 case REPCMD_NOP		:
- 			 if (cmd.eid!=REP.MERGE_EID.id)
- 				 addNop();
+		 case REPCMD_INSERT_ACK		:
+		 case REPCMD_DELETE_ACK		:
 			 forwardCommand(cmd);
 			 break;		 
 		 case REPCMD_CLOSE	:
@@ -284,7 +278,6 @@
 			 break;
 		 case SMCMD_END_MERGE :
 			 inputLock = false;
-			 prevSeq = seq;
 			 break;
 		 case SMCMD_QUIT_2 :
 			 if (cmd.eid!=eid) {
@@ -311,12 +304,6 @@
 		}
 	}
 
-	private void addNop() {
-		if (seq!=prevSeq) return;
-		// We haven't send any command, add nop before retransmition.
-		prevSeq = seq;
-		sendCommand(nop);
-	}
 
 	public int getPort() {
 		return port;