# HG changeset patch # User one # Date 1227080469 -32400 # Node ID a2efdec5cbfc3f2b43dfcafbfe44c0846379e30d # Parent 1d5b608f39dad5640693189adaf65d26217d9b16 insert_ack/delete_ack protocol all written. diff -r 1d5b608f39da -r a2efdec5cbfc rep/handler/Editor.java --- 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 sentList = new LinkedList(); 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(); diff -r 1d5b608f39da -r a2efdec5cbfc test/sematest/TestEditor.java --- 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 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;