comparison rep/handler/Editor.java @ 397:149c9a53fc37

half done ACK protocol
author one
date Sun, 23 Nov 2008 16:35:20 +0900
parents dc616339b00a
children 7de83b6a34e7
comparison
equal deleted inserted replaced
396:dc616339b00a 397:149c9a53fc37
37 else optimizer = new NullOptimizer(); //なにもしないけどOptimizer. 37 else optimizer = new NullOptimizer(); //なにもしないけどOptimizer.
38 translator = new Translator(eid,optimizer); 38 translator = new Translator(eid,optimizer);
39 } 39 }
40 40
41 41
42 public void translate(REPCommand command){ 42 public void translate(REPCommand command){
43 switch(command.cmd) {
44 case REPCMD_INSERT_ACK:
45 case REPCMD_DELETE_ACK:
46 if (command.eid==eid) {
47 // Second Phase が終わって同期が終了。
48 return;
49 }
50 checkReturnedCommand(command);
51 return;
52 }
43 if (command.eid == eid){ 53 if (command.eid == eid){
44 //エディタからの新たな編集コマンド 54 //エディタからの新たな編集コマンド
45 if (next==this) return; // singleton case 55 if (next==this) return; // singleton case
46 translator.transSendCmd(command); 56 translator.transSendCmd(command);
47 sentList.add(new REPCommand(command)); 57 sendEditorCommand(command);
48 assert(sentList.size()<limit);
49 next.send(command);
50 return; 58 return;
51 } else if (command.eid == REP.MERGE_EID.id){ 59 } else if (command.eid == REP.MERGE_EID.id){
52 //マージコマンドが返ってきた 60 //マージコマンドが返ってきた
53 if(translator.checkMergeConflict(command)){ 61 if(translator.checkMergeConflict(command)){
54 //マージ中にエディタからの割り込みがあった場合 62 //マージ中にエディタからの割り込みがあった場合
55 translator.getMergeAgain(this); 63 translator.getMergeAgain(this);
56 } 64 }
57 checkEndMerge(); 65 checkEndMerge();
58 } else if (command.eid == next.getEID()){ 66 } else if (command.eid == next.getEID()){
59 // 次のEditorで一周するコマンドが来た 67 // 次のEditorで一周するコマンドが来た
68 // この方法、あんまり良くない...
60 if (next==this) return; // singleton case 69 if (next==this) return; // singleton case
61 // これは、distributed case では、うまくいかないので、送り先のforwarder で処理する。 70 // これは、distributed case では、うまくいかないので、送り先のforwarder で処理する。
62 if (next.isDirect()) 71 if (next.isDirect()) {
72 REPCommand keep;
73 switch (command.cmd) {
74 case REPCMD_INSERT:
75 keep = new REPCommand(command);
76 keep.cmd = REP.REPCMD_INSERT_ACK;
77 sentList.add(keep);
78 ServerMainLoop.logger.writeLog("Editor eid:"+eid+" sentList = "+sentList);
79 break;
80 case REPCMD_DELETE:
81 keep = new REPCommand(command);
82 keep.cmd = REP.REPCMD_DELETE_ACK;
83 sentList.add(keep);
84 ServerMainLoop.logger.writeLog("Editor eid:"+eid+" sentList = "+sentList);
85 break;
86 }
63 ((Editor) next).checkReturnedCommand(command); 87 ((Editor) next).checkReturnedCommand(command);
64 else 88 } else
65 next.send(command); 89 next.send(command);
66 } else { 90 } else {
67 //他のエディタからの編集コマンド 91 //他のエディタからの編集コマンド
68 if (manager.hasWaitingCommand(channel)) { 92 if (manager.hasWaitingCommand(channel)) {
69 // We cannot do this operation before watingCommandQueue. 93 // We cannot do this operation before watingCommandQueue.
70 manager.addWaitingCommand(new PacketSet(channel, this, command)); 94 manager.addWaitingCommand(new PacketSet(channel, this, command));
71 } else if (isMerging()) { 95 } else if (isMerging()) {
72 manager.addWaitingCommand(new PacketSet(getChannel(), this, new REPCommand(command))); 96 manager.addWaitingCommand(new PacketSet(getChannel(), this, new REPCommand(command)));
73 } else { 97 } else {
74 switch(command.cmd) { 98 translator.transReceiveCmd(next,command);
75 case REPCMD_INSERT_ACK: 99 if(command.cmd==REP.REPCMD_DELETE) {
76 case REPCMD_DELETE_ACK: 100 // delete のundo用の文字列は、外に出す意味はない
77 startMerge(command); 101 command.string=null;
78 break;
79 default:
80 translator.transReceiveCmd(next,command);
81 } 102 }
103 sendEditorCommand(command);
82 } 104 }
83 } 105 }
84 return; 106 return;
107 }
108
109 private void sendEditorCommand(REPCommand command) {
110 REPCommand keep = new REPCommand(command);
111 switch(command.cmd) {
112 case REPCMD_INSERT:
113 keep.cmd = REP.REPCMD_INSERT_ACK;
114 break;
115 case REPCMD_DELETE:
116 keep.cmd = REP.REPCMD_DELETE_ACK;
117 break;
118 }
119 sentList.add(keep);
120 ServerMainLoop.logger.writeLog("Editor eid:"+eid+" sentList = "+sentList);
121 assert(sentList.size()<limit);
122 next.send(command);
85 } 123 }
86 124
87 boolean merge(REPCommand command) { 125 boolean merge(REPCommand command) {
88 //マージして送信 126 //マージして送信
89 return translator.catchOwnCommand(this); 127 return translator.catchOwnCommand(this);
99 String err = "Editor.checkReturnedCommand() : command = " + command + " prev="; 137 String err = "Editor.checkReturnedCommand() : command = " + command + " prev=";
100 err += prev==null?"null":prev.toString(); 138 err += prev==null?"null":prev.toString();
101 ServerMainLoop.logger.writeLog(err); 139 ServerMainLoop.logger.writeLog(err);
102 assert(false); 140 assert(false);
103 } 141 }
104 switch (command.cmd) {
105 case REPCMD_INSERT_ACK:
106 case REPCMD_DELETE_ACK:
107 // Second Phase が終わって同期が終了。
108 return;
109 case REPCMD_INSERT:
110 command.cmd = REP.REPCMD_INSERT_ACK;
111 break;
112 case REPCMD_DELETE:
113 command.cmd = REP.REPCMD_DELETE_ACK;
114 break;
115 }
116 startMerge(command); 142 startMerge(command);
117 return; 143 return;
118 } 144 }
119 145
120 private void startMerge(REPCommand command) { 146 private void startMerge(REPCommand command) {
121 preMergeCommand = command; 147 preMergeCommand = new REPCommand(command);
148 preMergeCommand.string = "";
122 // merge は必須だが、EditorのCommand実装をテストするには邪魔なので、off に出来るようにする。 149 // merge は必須だが、EditorのCommand実装をテストするには邪魔なので、off に出来るようにする。
123 if (noMergeMode) { 150 if (noMergeMode) {
124 endMerge(); 151 endMerge();
125 return; 152 return;
126 } 153 }
170 } 197 }
171 198
172 private void endMerge() { 199 private void endMerge() {
173 REPCommand mergeEnd = new REPCommand(REP.SMCMD_END_MERGE,sid,eid,seq(),0,""); 200 REPCommand mergeEnd = new REPCommand(REP.SMCMD_END_MERGE,sid,eid,seq(),0,"");
174 send(mergeEnd); 201 send(mergeEnd);
175 // send INSERT_ACK/DELETE_ACK as next editor's merge trigger 202 if (preMergeCommand.eid==eid) {
176 sentList.add(new REPCommand(preMergeCommand)); 203 // First Phase End, send ACK
177 next.send(preMergeCommand); 204 REPCommand keep = new REPCommand(preMergeCommand);
205 switch(keep.cmd) {
206 case REPCMD_INSERT:
207 keep.cmd = REP.REPCMD_INSERT_ACK;
208 break;
209 case REPCMD_DELETE:
210 keep.cmd = REP.REPCMD_DELETE_ACK;
211 break;
212 }
213 sentList.add(keep);
214 ServerMainLoop.logger.writeLog("Editor eid:"+eid+" sentList = "+sentList);
215 assert(sentList.size()<limit);
216 next.send(keep);
217 } else {
218 next.send(preMergeCommand);
219 }
220 preMergeCommand = null;
178 } 221 }
179 222
180 private boolean checkQuit() { 223 private boolean checkQuit() {
181 if (sentList.size()==0&&!isMerging()) { 224 if (sentList.size()==0&&!isMerging()) {
182 send(quit2); 225 send(quit2);
293 // state. Only this session manager knows it. 336 // state. Only this session manager knows it.
294 setQuit2(command); 337 setQuit2(command);
295 } else if (command.eid==eid) { 338 } else if (command.eid==eid) {
296 // if we handle in editor.manage(), this editor cannot distinguish this 339 // if we handle in editor.manage(), this editor cannot distinguish this
297 // and user input command from the editor. 340 // and user input command from the editor.
341 REPCommand keep;
298 switch(command.cmd) { 342 switch(command.cmd) {
299 case REPCMD_DELETE: 343 case REPCMD_DELETE_ACK:
344 case REPCMD_INSERT_ACK:
345 checkReturnedCommand(command);
346 return ;
300 case REPCMD_INSERT: 347 case REPCMD_INSERT:
301 case REPCMD_NOP: 348 keep = new REPCommand(command);
349 keep.cmd = REP.REPCMD_INSERT_ACK;
350 sentList.add(keep);
302 checkReturnedCommand(command); 351 checkReturnedCommand(command);
303 return; 352 return;
353 case REPCMD_DELETE:
354 keep = new REPCommand(command);
355 keep.cmd = REP.REPCMD_DELETE_ACK;
356 sentList.add(keep);
357 checkReturnedCommand(command);
358 return;
304 } 359 }
305 } 360 }
306 send(command); 361 send(command);
307 } 362 }
308 363