# HG changeset patch # User one@firefly.cr.ie.u-ryukyu.ac.jp # Date 1226323312 -32400 # Node ID 6f356d160e58b20439e2b236e698b95c89038b48 # Parent bba62c4ac3239f2ac8c2afb146571665214f93a0 IPv6 any address diff -r bba62c4ac323 -r 6f356d160e58 Todo --- a/Todo Mon Nov 10 22:19:34 2008 +0900 +++ b/Todo Mon Nov 10 22:21:52 2008 +0900 @@ -1,4 +1,33 @@ +Sun Oct 26 17:36:40 JST 2008 +Todo: (kono) +GUI のEditorの方が、どれがどれだか、さっぱりわからない。 +せめて、sessionを持っているかとか出ないとだめっぽい。 +なんか、NO_NAMEってのが最初に出るらしい。なんだ? + +Sun Oct 26 14:33:51 JST 2008 +Todo: (kono) +quit/close 処理が間違っているらしい。 + +Sat Oct 25 10:52:05 JST 2008 +Todo: (kono) +Editorからのmutli-sessoin の扱い、TestEditor でのmulti-session +の実装。REPNode.handle の中でreadしちゃうと、handle 間での処理 +の引き渡しが出来ない。handlerの切替えにkeyは必要。 + +一つのeditorの中で、同じsessionに複数selectすると、コマンドを +判定出来なくなる。今でも、新しくchannelを開けるなら複数セッション +をselectすることは可能。channelで識別しているので。 +新しいeditorが作られてしまうので、ダメなケースの判定は、直接接続し +ているSMでしか出来ない。と言うことは、selectのcancelのprotocolが +必要らしい。それは、結構、面倒。command に source editor id を +付けてやれば良いのだが... + +Todo: (kono) +text editor のバッファが増えるバグがあるらしい。 + Done: たぶん、quit/quit2が動いてない。close の処理のがまずいせい。 + Fri Oct 24 19:00:50 JST 2008 +Note: XML に editor がselectされているかどうかのflagがあった方が良い。 現状では、update はなんにも役に立たない。 @@ -12,7 +41,9 @@ Todo: (kono) やっぱり、END_MERGEが繰り返し出るバグがあるらしい。 - Done: Thu Oct 23 10:12:27 JST 2008 merge confilict 時にmode setを忘れてました。 + Done: Thu Oct 23 10:12:27 JST 2008 merge confilict 時にmode setを + 忘れてました。 + 結局、flag を入れて対症療法しました。 Wed Oct 22 02:31:27 JST 2008 @@ -22,12 +53,13 @@ だが... やっぱり、dummy editor ではなくて、専用のものを作らないと だめ? Done: Wed Oct 22 02:56:30 JST 2008 - ちょっとあれだが、next がdirecgtでない場合を判断して、向こうのforwarder側で - 処理するのが簡単らしい。 + ちょっとあれだが、next がdirecgtでない場合を判断して、向こうの + forwarder側で処理するのが簡単らしい。 Todo: (kono) Select後のupdateを流してないので、他の人が、そのsessionがselectされたのを 知り得ない。なので、複数のjoin_ackがありえる。 + Done: Sun Oct 26 17:39:05 JST 2008 Mon Oct 20 16:38:39 JST 2008 diff -r bba62c4ac323 -r 6f356d160e58 rep/SessionManager.java --- a/rep/SessionManager.java Mon Nov 10 22:19:34 2008 +0900 +++ b/rep/SessionManager.java Mon Nov 10 22:21:52 2008 +0900 @@ -51,7 +51,7 @@ // Session Manager Channel may have dummy editors. EditorList editorList = new EditorList(); // Queue limit for debugging purpose. - static final int packetLimit = 200; + static final int packetLimit = 400; // globalSessionID = SessionManagerID * MAXID + localSessionID private static final int MAXID = 10000; @@ -118,7 +118,7 @@ REPSocketChannel sessionchannel = REPSocketChannel.create(new REPCommandPacker()); sessionchannel.connect(addr); while(!sessionchannel.finishConnect()); - REPNode sm = new FirstConnector(this); + REPNode sm = new FirstConnector(this,sessionchannel); registerChannel(sessionchannel, sm); sm_join(sm); }catch (IOException e) { @@ -208,9 +208,9 @@ } private REPNode createSessionForwarder(int sid, REPNode editor) { - REPNode f = new Forwarder(this); + REPNode f = new Forwarder(this,editor.channel); f.setEID(makeID(editorList.newEid())); - f.setChannel(editor.channel); // incoming channel + // f.setChannel(editor.channel); // incoming channel f.setHost(myHost); f.setSID(sid); return f; @@ -237,7 +237,7 @@ */ public REPNode newEditor(REPSocketChannel channel) { int eid = makeID(editorList.newEid()); - REPNode editor = new Editor(this, eid, channel); + REPNode editor = new Editor(eid, this, channel); editorList.add(editor); return editor; } @@ -448,7 +448,7 @@ // すでに channelはSessionManager Idを持っていて、 // direct link ではないので、 // channel を持たないForwarderとして登録する - sm = new Forwarder(this); + sm = new Forwarder(this,null); } else { sm = forwarder; } @@ -547,7 +547,7 @@ } else return; } else { - editor = new Editor(this, command.eid); + editor = new Editor(manager, command.eid); } editor.setName(command.string); editor.setSID(command.sid); diff -r bba62c4ac323 -r 6f356d160e58 rep/SessionManagerList.java --- a/rep/SessionManagerList.java Mon Nov 10 22:19:34 2008 +0900 +++ b/rep/SessionManagerList.java Mon Nov 10 22:21:52 2008 +0900 @@ -13,7 +13,7 @@ private static final long serialVersionUID = 1L; private int mySMID=0; private int smid_root=0; - private REPNode parent=new NullForwarder(null); + private REPNode parent=new NullForwarder(null,null); private LinkedList waiting= new LinkedList(); diff -r bba62c4ac323 -r 6f356d160e58 rep/gui/RPanel.java --- a/rep/gui/RPanel.java Mon Nov 10 22:19:34 2008 +0900 +++ b/rep/gui/RPanel.java Mon Nov 10 22:21:52 2008 +0900 @@ -106,9 +106,12 @@ }else if(event.getSource() == selectButton){ //System.out.println("RPanel.actionPerformed() : editorSelectedRow = " + editor_table.getSelectedRow()); + int selectedSession = session_table.getSelectedRow(); + if (selectedSession<0) return; // no sessin is selected + int selectedEditor = editor_table.getSelectedRow(); listener.buttonPressed( - new SelectButtonEvent(editorList.get(editor_table.getSelectedRow()), - sessionList.get(session_table.getSelectedRow()))); + new SelectButtonEvent(editorList.get(selectedEditor), + sessionList.get(selectedSession))); }else if(event.getSource() == closeButton){ listener.buttonPressed(new CloseButtonEvent(sessionList.get(session_table.getSelectedRow()), listener)); } diff -r bba62c4ac323 -r 6f356d160e58 rep/handler/Dispatcher.java --- a/rep/handler/Dispatcher.java Mon Nov 10 22:19:34 2008 +0900 +++ b/rep/handler/Dispatcher.java Mon Nov 10 22:21:52 2008 +0900 @@ -17,8 +17,10 @@ */ public class Dispatcher extends Forwarder { - public Dispatcher(SessionManager manager) { - super(manager); + + public Dispatcher(SessionManager manager, + REPSocketChannel channel) { + super(manager, channel); } public void setQuit2(REPCommand cmd) { @@ -35,14 +37,13 @@ } - public void handle(REPSelectionKey key) throws IOException { + @Override + public void handle(REPCommand command, REPSelectionKey key) throws IOException { /* * SessionManagerから来たコマンドは、Editor関係のコマンドは、 * sessionとeidを判定して、そのeditorにforwardしてやれば良い。 * 残りは、manager.manage() で処理する。 */ - REPSocketChannel channel = key.channel1(); - REPCommand command = channel.read(); ServerMainLoop.logger.writeLog("REPHandlerImpl.handle() : command = " + command); if (manager.sessionManage(this, command)) return; diff -r bba62c4ac323 -r 6f356d160e58 rep/handler/Editor.java --- a/rep/handler/Editor.java Mon Nov 10 22:19:34 2008 +0900 +++ b/rep/handler/Editor.java Mon Nov 10 22:21:52 2008 +0900 @@ -16,28 +16,26 @@ public class Editor extends Forwarder { private Translator translator; + // REPCommands we are going to send to the next editor private List sentList = new LinkedList(); - // REPCommands we are going to send to the next editor - //private REPCommand quit2 = null; - private SessionManager manager; private REPCommand quit2=null; + private boolean merging; static final boolean doOptimize = true; public Editor(SessionManager manager,int editorNo){ - super(manager); - this.manager = manager; + // no translator case + super(manager, null); + } + + public Editor(int editorNo, SessionManager manager,REPSocketChannel channel){ + super(editorNo,manager,channel); eid = editorNo; REPCommandOptimizer optimizer; if (doOptimize) optimizer = new DeleteInsertOptimizer(); //タカノがつくったおぷてぃまいざ else optimizer = new NullOptimizer(); //なにもしないけどOptimizer. translator = new Translator(eid,optimizer); - } - - public Editor(SessionManager manager,int editorNo, REPSocketChannel channel){ - this(manager,editorNo); - this.channel = channel; - } + public void translate(REPCommand command){ @@ -99,6 +97,7 @@ // 送らないで良い場合もある? REPCommand cmd = new REPCommand(REP.SMCMD_START_MERGE,command.sid,REP.SM_EID.id,seq(),0,""); send(cmd); + merging = true; // Session Manager 側で、このeditorへの他のeditorからの // 入力を止めて、merge にそなえる。merge は、eidtor 側から // ACKが来てから始まる。 @@ -117,7 +116,8 @@ @Override public void setEID(int eid) { this.eid = eid; - translator.setEid(eid); + if (translator!=null) + translator.setEid(eid); } public String toString(){ @@ -131,9 +131,12 @@ void checkEndMerge() { - if(translator.isMerging()) return; - REPCommand mergeEnd = new REPCommand(REP.SMCMD_END_MERGE,eid,sid,seq(),0,""); - send(mergeEnd); + if (merging) { + if(translator.isMerging()) return; + REPCommand mergeEnd = new REPCommand(REP.SMCMD_END_MERGE,eid,sid,seq(),0,""); + send(mergeEnd); + merging = false; + } if (quit2!=null) checkQuit(); } @@ -147,17 +150,17 @@ } @Override - public boolean manage(REPCommand receivedCommand) { + public boolean manage(REPCommand command) { - switch(receivedCommand.cmd){ + switch(command.cmd){ // Editor Command case REPCMD_DELETE: case REPCMD_INSERT: case REPCMD_NOP: { - translate(receivedCommand); + translate(command); break; } @@ -165,7 +168,7 @@ { // マージの処理と次のエディタへコマンドを送信する処理 translator.mergeAck(); - if (!merge(receivedCommand)) { + if (!merge(command)) { // nothing to do, send END_MERGE checkEndMerge(); } @@ -174,19 +177,19 @@ case SMCMD_SYNC: if (isMaster()) - send(receivedCommand); + send(command); else - next.send(receivedCommand); + next.send(command); case SMCMD_QUIT: { - next.send(receivedCommand); + next.send(command); break; } case SMCMD_QUIT_2: { // QUIT_2 is returned. - if (receivedCommand.eid!=eid) { + if (command.eid!=eid) { // stop this editor unless this is the start, starter will stopped // by QUIT_2_ACK manager.remove(this); @@ -195,9 +198,9 @@ // merge is processed. // this does not work in distributed case. if (next.isDirect()) - next.setQuit2(receivedCommand); + next.setQuit2(command); else - next.send(receivedCommand); + next.send(command); break; } case SMCMD_QUIT_2_ACK: @@ -213,10 +216,17 @@ @Override - public void handle(REPSelectionKey key) throws IOException { - REPSocketChannel channel = key.channel1(); - REPCommand command = channel.read(); + public void handle(REPCommand command, REPSelectionKey key) throws IOException { ServerMainLoop.logger.writeLog("REPHandlerImpl.handle() read : command = " + command +" from "+channel); + if (command.cmd==REP.SMCMD_JOIN||command.cmd==REP.SMCMD_PUT) { + assert false; + // 若干問題があるらしい + next = new Forwarder(manager,next.channel); + REPNode first = new FirstConnector(manager,channel); + first.handle(command, key); + key.attach(new Dispatcher(manager,channel)); + return; + } if (manager.sessionManage(this, command)) return; manage(command); } diff -r bba62c4ac323 -r 6f356d160e58 rep/handler/FirstConnector.java --- a/rep/handler/FirstConnector.java Mon Nov 10 22:19:34 2008 +0900 +++ b/rep/handler/FirstConnector.java Mon Nov 10 22:21:52 2008 +0900 @@ -13,15 +13,19 @@ public class FirstConnector extends Forwarder { - public FirstConnector(SessionManager manager) { - super(manager); + + + public FirstConnector(SessionManager manager, + REPSocketChannel channel) { + super(manager,channel); } - + public void cancel(REPSocketChannel socketChannel) { manager.remove(socketChannel); } - public void handle(REPSelectionKey key) throws IOException { + @Override + public void handle(REPCommand command, REPSelectionKey key) throws IOException { /* * 接続要求は、EditorかSlave Editorで、 *    join, put, sm_join @@ -29,8 +33,6 @@ * sm_join_ack */ REPNode fw; - REPSocketChannel channel = key.channel1(); - REPCommand command = channel.read(); ServerMainLoop.logger.writeLog("FirstConnector: command = " + command); switch(command.cmd) { case SMCMD_JOIN: @@ -63,14 +65,14 @@ } case SMCMD_SM_JOIN: { - fw = new Dispatcher(manager); // FirstConnector? + fw = new Dispatcher(manager,channel); // FirstConnector? manager.addWaitingSessionManager(fw, command); break; } case SMCMD_SM_JOIN_ACK: manager.setSessionManagerID(command.sid); manager.afterConnect(); - fw = new Dispatcher(manager); + fw = new Dispatcher(manager,channel); manager.setParent(fw); break; default: throw new IOException(); diff -r bba62c4ac323 -r 6f356d160e58 rep/handler/Forwarder.java --- a/rep/handler/Forwarder.java Mon Nov 10 22:19:34 2008 +0900 +++ b/rep/handler/Forwarder.java Mon Nov 10 22:21:52 2008 +0900 @@ -21,11 +21,15 @@ // REPCommands we sent to the next editor final int limit=100; // debugging purpose, assert check only final REPLogger ns = REPLogger.singleton(); - SessionManager manager; - public REP mode = null; - - public Forwarder(SessionManager manager) { - this.manager = manager; + + public Forwarder(SessionManager manager, + REPSocketChannel channel) { + super(manager,channel); + } + + public Forwarder(int editorNo, SessionManager manager, + REPSocketChannel channel) { + super(editorNo,manager,channel); } public int seq() { @@ -81,11 +85,13 @@ return channel.getLocalHostName(); } + @Override public void cancel(REPSocketChannel socketChannel) { manager.remove(socketChannel); } - public void handle(REPSelectionKey key) throws IOException { + @Override + public void handle(REPCommand command, REPSelectionKey key) throws IOException { assert false; } diff -r bba62c4ac323 -r 6f356d160e58 rep/handler/NullForwarder.java --- a/rep/handler/NullForwarder.java Mon Nov 10 22:19:34 2008 +0900 +++ b/rep/handler/NullForwarder.java Mon Nov 10 22:21:52 2008 +0900 @@ -14,33 +14,43 @@ */ public class NullForwarder extends Forwarder { - public NullForwarder(SessionManager manager) { - super(manager); + + public NullForwarder(SessionManager manager, + REPSocketChannel channel) { + super(manager, channel); } - + + @Override public void send(REPCommand command) { } + + @Override public void cancel(REPSocketChannel socketChannel) { } - public void handle(REPSelectionKey key) throws IOException { + @Override + public void handle(REPCommand command, REPSelectionKey key) throws IOException { } + @Override public boolean manage(REPCommand command) { return true; } + @Override public boolean isEditor() { return false; } + @Override public boolean isForwarder() { return false; } + @Override public boolean isDirect() { return false; } diff -r bba62c4ac323 -r 6f356d160e58 rep/handler/REPNode.java --- a/rep/handler/REPNode.java Mon Nov 10 22:19:34 2008 +0900 +++ b/rep/handler/REPNode.java Mon Nov 10 22:21:52 2008 +0900 @@ -5,6 +5,7 @@ import rep.REP; import rep.REPCommand; import rep.Session; +import rep.SessionManager; import rep.channel.REPSelectionKey; import rep.channel.REPSocketChannel; @@ -28,14 +29,21 @@ public REP mode; public REPSocketChannel channel; public REPNode next; + public SessionManager manager; public REPNode() { } - - public REPNode(int eid, REPSocketChannel channel) { + + public REPNode(int eid, SessionManager manager, REPSocketChannel channel) { this.eid = eid; this.channel = channel; + this.manager = manager; + } + + public REPNode(SessionManager manager, REPSocketChannel channel) { + this.channel = channel; + this.manager = manager; } public String getName() { @@ -94,7 +102,7 @@ if (host==null) host = editor.host; } - public abstract void handle(REPSelectionKey key) throws IOException; + public abstract void handle(REPCommand command, REPSelectionKey key) throws IOException; public abstract void cancel(REPSocketChannel channel1) ; diff -r bba62c4ac323 -r 6f356d160e58 rep/xml/SessionXMLDecoder.java --- a/rep/xml/SessionXMLDecoder.java Mon Nov 10 22:19:34 2008 +0900 +++ b/rep/xml/SessionXMLDecoder.java Mon Nov 10 22:21:52 2008 +0900 @@ -84,15 +84,17 @@ Element elementFile = (Element) nodelistEditorFile.item(0); String file = elementFile.getFirstChild().getNodeValue(); - Editor editor = new Editor(null, 0); - editor.setHost(host);/* editor.setPort(port)*/; editor.setName(file); editor.setEID(Integer.parseInt(eid)); + int id = Integer.parseInt(eid); + Editor editor = new Editor(null, id); + editor.setHost(host);/* editor.setPort(port)*/; editor.setName(file); session = new Session(sid, editor); session.addEditor(editor); sessionlist.put(sid,session); }else { - Editor editor = new Editor(null, 0); - editor.setHost(host);/* editor.setPort(port)*/; editor.setName(null); editor.setEID(Integer.parseInt(eid)); + int id = Integer.parseInt(eid); + Editor editor = new Editor(null, id); + editor.setHost(host);/* editor.setPort(port)*/; editor.setName(null); if(session != null){ session.addEditor(editor); } diff -r bba62c4ac323 -r 6f356d160e58 test/RepCommandOptimizeTest.java --- a/test/RepCommandOptimizeTest.java Mon Nov 10 22:19:34 2008 +0900 +++ b/test/RepCommandOptimizeTest.java Mon Nov 10 22:21:52 2008 +0900 @@ -1,8 +1,12 @@ package test; +import static org.junit.Assert.*; + import java.util.LinkedList; import java.util.List; +import org.junit.Test; + import rep.REPCommand; import rep.REP; import rep.optimizers.NullOptimizer; @@ -85,7 +89,15 @@ text.printAllText(); } + public static void main(String[] s){ + RepCommandOptimizeTest t = new RepCommandOptimizeTest(); + t.main0(); + } + + @Test + public void main0(){ + REPCommandOptimizer rco; if (true) rco = new DeleteInsertOptimizer(); // @@ -107,7 +119,6 @@ } - private static void test(REPCommandOptimizer rco, List cmdlist, Text text1, Text text2) { List result; // optimize @@ -117,6 +128,7 @@ // this command list applied to other text, and print it. text2.edit(result); // check two texts. + assertEquals(text1.equals(text2),true); if(!text1.equals(text2)){ System.out.println("two texts not match"); print(cmdlist, result, text1, text2); diff -r bba62c4ac323 -r 6f356d160e58 test/Text.java --- a/test/Text.java Mon Nov 10 22:19:34 2008 +0900 +++ b/test/Text.java Mon Nov 10 22:21:52 2008 +0900 @@ -7,36 +7,46 @@ import rep.REPCommand; import rep.REP; -public class Text { +public class Text extends LinkedList { + - List strList; - + /** + * + */ + private static final long serialVersionUID = 1L; + public Text(String[] _strings){ - strList = new LinkedList(Arrays.asList(_strings)); + super(Arrays.asList(_strings)); } + public Text(List _strings){ - strList = new LinkedList(_strings); + super(_strings); } public String insert(int i, String str){ - assert 0<=i && i<=strList.size(); - strList.add(i, str); + assert 0<=i && i<=size(); + add(i, str); return null; } + public String delete(int i){ - assert 0<=i && i=size()) return ""; + // assert 0<=i && i cmdlist){ for (REPCommand cmd: cmdlist){ edit(cmd); } } - public int size(){ - return strList.size(); - } public void printAllText(){ - for( String str: strList){ + for( String str: this){ System.out.println(str); } } - public boolean equals(Text _target){ - return strList.equals(_target.strList); - } } diff -r bba62c4ac323 -r 6f356d160e58 test/XMLTest.java --- a/test/XMLTest.java Mon Nov 10 22:19:34 2008 +0900 +++ b/test/XMLTest.java Mon Nov 10 22:21:52 2008 +0900 @@ -14,13 +14,13 @@ public static void main(String[] args){ - Editor editor = new Editor(null,0, null); + Editor editor = new Editor(0,null,null); editor.setEID(1); editor.setHost("firefly.cr.ie.u-ryukyu.ac.jp"); //editor.setPort("56789"); editor.setName("Test.java"); - Editor editor2 = new Editor(null,1, null); + Editor editor2 = new Editor(1,null,null); editor2.setEID(2); editor2.setHost("teto.cr.ie.u-ryukyu.ac.jp"); //editor2.setPort("45678"); diff -r bba62c4ac323 -r 6f356d160e58 test/sematest/TestEditor.java --- a/test/sematest/TestEditor.java Mon Nov 10 22:19:34 2008 +0900 +++ b/test/sematest/TestEditor.java Mon Nov 10 22:21:52 2008 +0900 @@ -39,6 +39,7 @@ private boolean inputLock=false; public boolean detached=false; public boolean master=false; + REPCommand quit=null; private int syncCounter=0; private boolean hasInputLock=false; private int port; @@ -62,7 +63,7 @@ cmds.add(new REPCommand(REP.SMCMD_PUT,0,0,0,0,name+"-file")); cmds.add(new REPCommand(REP.REPCMD_INSERT,0,0,0,0,"m0")); cmds.add(new REPCommand(REP.REPCMD_DELETE,0,0,0,0,"m0")); - cmds.add(new REPCommand(REP.SMCMD_QUIT,0,0,0,0,"")); + //cmds.add(new REPCommand(REP.SMCMD_QUIT,0,0,0,0,"")); } else { text = new Text(new String[0]); cmds.add(new REPCommand(REP.SMCMD_JOIN,0,0,0,0,name)); @@ -182,7 +183,7 @@ * clients simply disconnect from the session manager. */ cmds.clear(); - sendCommand(cmd); + quit = cmd; break; case SMCMD_JOIN: case SMCMD_PUT: @@ -197,9 +198,14 @@ assert(false); } } else { - if(syncCounter==0) + if(syncCounter==0) { // no more command to send, and we don't have syncCounter timeout = 0; + if (quit!=null) { + sendCommand(quit); + quit=null; + } + } } } @@ -229,9 +235,6 @@ addNop(); forwardCommand(cmd); break; - case REPCMD_INSERT_ACK : - assert(false); - break; case REPCMD_DELETE : String del=""; if(cmd.lineno>text.size()) { @@ -242,14 +245,12 @@ cmd.setString(del); forwardCommand(cmd); break; - case REPCMD_DELETE_ACK : - assert(false); - break; case REPCMD_NOP : if (cmd.eid!=REP.MERGE_EID.id) addNop(); forwardCommand(cmd); - break; case REPCMD_CLOSE : + break; + case REPCMD_CLOSE : case REPCMD_CLOSE_2 : assert(false); break; @@ -275,20 +276,15 @@ // stop input processing after this command cmds.clear(); break; - case SMCMD_QUIT_ACK : - assert(false); - break; case SMCMD_START_MERGE : // lock user input during merge (optional) inputLock = hasInputLock; cmd.cmd = REP.SMCMD_START_MERGE_ACK; sendCommand(cmd); break; - case SMCMD_START_MERGE_ACK : - assert(false); - break; case SMCMD_END_MERGE : inputLock = false; + prevSeq = seq; break; case SMCMD_QUIT_2 : if (cmd.eid!=eid) { @@ -318,8 +314,8 @@ private void addNop() { if (seq!=prevSeq) return; // We haven't send any command, add nop before retransmition. + prevSeq = seq; sendCommand(nop); - prevSeq = seq; } public int getPort() {