changeset 462:d295e84c5e03

slow merge won't work. select time out.
author one
date Fri, 01 Oct 2010 15:58:20 +0900
parents e7eeb8be0de1
children 3c2918368de3
files Todo rep/ServerMainLoop.java rep/handler/Editor.java
diffstat 3 files changed, 149 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/Todo	Fri Sep 24 17:17:37 2010 +0900
+++ b/Todo	Fri Oct 01 15:58:20 2010 +0900
@@ -1,3 +1,115 @@
+Fri Oct  1 10:09:41 JST 2010
+
+やっぱり、そんなに簡単には動かないか。slow merge だと dead lock する。
+
+SMCMD_QUITをSMCMD_QUIT_2に変えているのは誰? Editor 側でやっているのかぁ。
+
+Tue Sep 28 10:43:14 JST 2010
+
+廻る順序でコマンド順は確定する。
+    方法は三つ
+        nop 前置方式
+        slow merge 方式 (二周後に確定)
+        sort interval 方式
+
+Editor1のc(eid=1) は、e(eid=2) よりは後になる。しかし、今の
+方法だと前だと判断されてしまう。nop 方式だと、その前に付く
+ので、そこで区切られる。
+
+ea(eid=2)とnopは同じ意味だが、区別する方法は?
+
+    START_MERGE INSET DELETE END_MERGE
+
+となるはず。
+
+    Editor1 では、sm e(eid=2) em c(eid=1)
+    Editor3 では、sm e(eid=2) c(eid=1) em
+
+となる? 
+
+em 後がある em 後へ
+sm-em間が空 ->sm-em 間へ
+sm-em間にコマンドがある ->  
+    同じsort interval  ->sm-em へ
+    新しいsort interval  ->em以降 へ
+
+Merge 後に sm-em は sm 以前に移される。
+em 以降の次のsort interval がsm-em に移動。(全部?)
+
+sort interval とは何? (良い質問だな〜)
+
+    eid の順序の一塊
+    新しい自分のコマンドは新しいsort interval を作る
+
+(いけそうではあるな...)
+
+途中の editor の脱落とかあると、どうしても同期がずれる?
+再送の仕組みは?
+
+Fri Sep 24 17:42:50 JST 2010
+
+    Editor3   Editor2    Editor1 
+              e(eid=2)
+                         e(eid=2)
+    e(eid=2)             c(eid=1)
+    c(eid=1)  e(eid=2)
+              c(eid=1)   ea(eid=2)*
+    ea(eid=2)*           c(eid=1)
+    ca(eid=1)*ea(eid=2)*
+              ca(eid=1)*
+                         ca(eid=1)*
+
+    [e,c]     [e,c]      [e,c]
+
+うーん、ack のみで merge するので良さそう。いや、そうすると、
+二周目の間にコマンドが入るけど、その扱いは?
+
+あ、そうか。他のeditorからのコマンドの前に自分のコマンドを入れる
+ってのがあったような気がする。二周目のackは、それを実現できない
+のか。
+
+    Editor3   Editor2    Editor1 
+              e(eid=2)
+                         1e(eid=2)
+    31e(eid=2)           c(eid=1)
+    3c(eid=1) 231e(eid=2)*
+              23c(eid=1) 231*
+    23                   23c(eid=1)*
+    12          23                
+    ca(eid=1)*ea(eid=2)*
+              ca(eid=1)*
+                         ca(eid=1)*
+
+    [c,e]     [c,e]      [c,e]
+
+う、結構わからんな。
+
+Fri Sep 24 17:42:50 JST 2010
+
+順序がずれる問題は、送信キューをEditor localに持つことで解消。
+
+結果がおかしいことがあるのは、(* は merge operation )
+
+    Editor1   Editor2    Editor3 
+              e(eid=2)
+                         e(eid=2)
+    e(eid=2)             c(eid=1)
+    c(eid=1)  e(eid=2)*
+              c(eid=1)   ea(eid=2)*
+    ea(eid=2)*           c(eid=1)
+    ca(eid=1) ea(eid=2)            
+              ca(eid=1)  
+                         ca(eid=1)  
+
+    [e,c]     [c,e]      [e,c]
+
+と巡回させた時に、Editor2 で e(eid=2) が確定してしまうかららしい。
+つまり eid=1 か ack を待てば良い。(ack は all eid と考えて良い)
+
+と言うことは、ack のみで merge するべきだってこと? 
+
+それでは、だめなみたいだなぁ。
+
 Thu Sep 23 14:57:57 JST 2010
 
 やっぱり、send が
--- a/rep/ServerMainLoop.java	Fri Sep 24 17:17:37 2010 +0900
+++ b/rep/ServerMainLoop.java	Fri Oct 01 15:58:20 2010 +0900
@@ -69,7 +69,7 @@
 				   //continue;
 			}
 			// now we can wait for input packet or event
-			selector.select();
+			selector.select(1);
 			select();
 		}
 	}
--- a/rep/handler/Editor.java	Fri Sep 24 17:17:37 2010 +0900
+++ b/rep/handler/Editor.java	Fri Oct 01 15:58:20 2010 +0900
@@ -18,13 +18,14 @@
 	// REPCommands we are going to send to the next editor
 	private LinkedList<REPCommand> sentList = new LinkedList<REPCommand>();
 	public LinkedList<REPCommand> waitingCommandInMerge= new LinkedList<REPCommand>();
-	private REPCommand quit2=null;
+	private REPCommand quit_2=null;
 	private REPCommand preMergeCommand;
 	private boolean merging;
 	private REPCommand mergeMark = new REPCommand(REP.SMCMD_START_MERGE, 0,0, 0, 0, "");
 	public static boolean noMergeMode=false;
 	static final boolean doOptimize = false;
 	private LinkedList<REPCommand> writeQueue = new LinkedList<REPCommand>(); 
+	static boolean slowMerge = true;
 
 	public Editor(SessionManager manager,int editorNo){
 		// no translator case
@@ -87,6 +88,11 @@
 		case REPCMD_INSERT_ACK:
 		case REPCMD_DELETE_ACK:
 			if (command.eid==eid) {
+				if (slowMerge) {
+					checkReturnedCommand(command);
+					checkQuit();
+					return;
+				}
 				// Second Phase が終わって同期が終了。
 				// SessionManager.logger.writeLog("Complete "+command);
 				checkAck(command);
@@ -116,7 +122,12 @@
 			} 
 			if (command.eid == eid){ 
 				// 編集コマンドが一周して来た
-				checkReturnedCommand(command);
+				if (slowMerge) {
+					checkAck(command);
+					sendAck(command);
+				} else {
+					checkReturnedCommand(command);
+				}
 				return;
 			}
 
@@ -251,11 +262,6 @@
 	 * @param command
 	 */
 	void checkReturnedCommand(REPCommand command) {
-		startMerge(command);
-		return;
-	}
-
-	private void startMerge(REPCommand command) {
 		ServerMainLoop.logger.writeLog("Editor"+eid+": startMerge "+command);
 		preMergeCommand = new REPCommand(command);
 		// merge は必須だが、EditorのCommand実装をテストするには邪魔なので、off に出来るようにする。
@@ -293,7 +299,7 @@
 
 	@Override
 	public void setQuit2(REPCommand cmd) {
-		quit2 = cmd;
+		quit_2 = cmd;
 		checkQuit();
 		// do not send quit2 until we received all pending
 		// command
@@ -321,7 +327,7 @@
 			endMerge();
 			merging = false;
 		}
-		if (quit2!=null) checkQuit();
+		if (quit_2!=null) checkQuit();
 	}
 
 
@@ -331,17 +337,8 @@
 		sendToEditor(mergeEnd);
 		checkAck(preMergeCommand);
 		if (preMergeCommand.eid==eid) {
-			// First Phase End, send ACK
-			REPCommand keep = new REPCommand(preMergeCommand);
-			switch(keep.cmd) {
-			case REPCMD_INSERT: keep.cmd = REP.REPCMD_INSERT_ACK;break;
-			case REPCMD_DELETE: keep.cmd = REP.REPCMD_DELETE_ACK;break;
-			default: assert(false);
-			}
-			sentList.addLast(preMergeCommand);
-			//ServerMainLoop.logger.writeLog("Editor eid:"+eid+" sentList = "+sentList);
-			assert(sentList.size()<limit);
-			next.send(keep);
+			if (!slowMerge)
+				sendAck(preMergeCommand);
 		} else {
 			next.send(preMergeCommand);
 		}
@@ -350,10 +347,24 @@
 		preMergeCommand = null;
 	}
 
+	private void sendAck(REPCommand command) {
+		REPCommand keep = new REPCommand(command);
+		// First Phase End, send ACK
+		switch(keep.cmd) {
+		case REPCMD_INSERT: keep.cmd = REP.REPCMD_INSERT_ACK;break;
+		case REPCMD_DELETE: keep.cmd = REP.REPCMD_DELETE_ACK;break;
+		default: assert(false);
+		}
+		sentList.addLast(command);
+		//ServerMainLoop.logger.writeLog("Editor eid:"+eid+" sentList = "+sentList);
+		assert(sentList.size()<limit);
+		next.send(keep);
+	}
+
 	private boolean checkQuit() {
-		if (quit2!=null && sentList.size()==1&&!isMerging() && waitingCommandInMerge.size()==0) {
-			sendToEditor(quit2);
-			quit2 = null;
+		if (quit_2!=null && sentList.size()==1&&!isMerging() && waitingCommandInMerge.size()==0) {
+			sendToEditor(quit_2);
+			quit_2 = null;
 			return true;
 		}
 		return false;
@@ -432,9 +443,9 @@
 	private boolean isMergeCommand(REPCommand command) {
 		switch(command.cmd) {
 		case REPCMD_INSERT: case REPCMD_DELETE:
-			return command.eid==eid;
+			return slowMerge?false:command.eid==eid;
 		case REPCMD_INSERT_ACK: case REPCMD_DELETE_ACK:
-			return command.eid!=eid;
+			return slowMerge?true:command.eid!=eid;
 		}
 		return false;
 	}