Mercurial > hg > RemoteEditor > REPSessionManager
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; }