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