# HG changeset patch # User one@firefly.cr.ie.u-ryukyu.ac.jp # Date 1226323174 -32400 # Node ID bba62c4ac3239f2ac8c2afb146571665214f93a0 # Parent 1fca50ce3508badc07d2d5c12b084ac6c361750b sync-option diff -r 1fca50ce3508 -r bba62c4ac323 Todo --- a/Todo Mon Nov 10 22:18:14 2008 +0900 +++ b/Todo Mon Nov 10 22:19:34 2008 +0900 @@ -1,7 +1,18 @@ +Fri Oct 24 19:00:50 JST 2008 + XML に editor がselectされているかどうかのflagがあった方が良い。 + 現状では、update はなんにも役に立たない。 + +Thu Oct 23 10:31:58 JST 2008 + +Todo: (kono) +UPDATE/UPDATE_ACKが出ない。 + Done: Fri Oct 24 19:00:50 JST 2008 + Wed Oct 22 19:53:59 JST 2008 Todo: (kono) やっぱり、END_MERGEが繰り返し出るバグがあるらしい。 + Done: Thu Oct 23 10:12:27 JST 2008 merge confilict 時にmode setを忘れてました。 Wed Oct 22 02:31:27 JST 2008 @@ -261,6 +272,8 @@ Todo: Optimizerを使った場合のテスト (kono) 行番号0があるとだめらしい。 + Done: (takano) Thu Oct 23 13:05:52 JST 2008 + Todo: manager.remove(editor) の動作のタイミング、 channel closeの扱い @@ -282,7 +295,8 @@ Done:Sat Oct 11 22:28:49 JST 2008 Todo: -SessionManager の向うにあるeditorにREPCommandを送るコードがない。Editor 扱いしても良いが、Editor が複雑すぎるので、それは好ましくない。Editor に nextChannelを持たせるのが良いか? (kono) +SessionManager の向うにあるeditorにREPCommandを送るコードがない。Editor 扱いしても良いが、 +Editor が複雑すぎるので、それは好ましくない。Editor に nextChannelを持たせるのが良いか? (kono) Done: Forwarder を作った Todo: @@ -305,7 +319,8 @@ Done: Mon Oct 6 16:40:38 JST 2008 (kono) Todo: SessionMnager のmessageをREPLogger baseに書き換える。 (kono) - + Done: Thu Oct 23 13:05:52 JST 2008 + Wed Oct 1 15:35:44 JST 2008 Todo: SessionManager 複数のコマンドをまとめてeditorに送るとdead lockする diff -r 1fca50ce3508 -r bba62c4ac323 rep/SessionManager.java --- a/rep/SessionManager.java Mon Nov 10 22:18:14 2008 +0900 +++ b/rep/SessionManager.java Mon Nov 10 22:19:34 2008 +0900 @@ -61,6 +61,8 @@ private REPNode sm_join_channel; // Routing table for session and session manager. private RoutingTable routingTable = new RoutingTable(this); + // sync option + public boolean sync = true; static public REPLogger logger = REPLogger.singleton(); @@ -169,7 +171,11 @@ private void selectSession0(int sid, Session session, int eid, REPNode editor) { if (editor.isDirect()&&editor.getEID()==eid) { - selectSession(sid, session, editor.getEID(), editor); + REPCommand command = new REPCommand(); + command.setSID(sid); + command.setEID(eid); + command.setString(session.getName()); + editor.selectSession(command, session); } else { // we don't have this editor, search the editor first. REPNode next = routingTable.toSessionManager(getSMID(eid)); @@ -183,35 +189,7 @@ } } - /* - * Select Session Protocol handler - * called from GUI or incoming SMCMD_SELECT command. - */ - private void selectSession(int sid, Session session, int eid, REPNode editor) { - if(session.hasOwner()){ - // we have selected session. - REPCommand sendCommand = new REPCommand(); - if (editor.isDirect()&&editor.getEID()==eid) { - // Found directly connected joined editor. Send join_ack(). - session.addForwarder(editor); - sendUpdate(session.getSID()); - sendCommand.setCMD(REP.SMCMD_JOIN_ACK); - } else { - // We have a session, but joined editor is on the other sm. - // SELECT_ACK is sent to the session ring to - // find out the joined editor. - sendCommand.setCMD(REP.SMCMD_SELECT_ACK); - } - sendCommand.setSID(sid); - sendCommand.string = session.getName(); - sendCommand.setEID(eid); - editor.send(sendCommand); - }else { - forwardSelect(sid, session, eid, editor); - } - } - - private void forwardSelect(int sid, Session session, int eid, + public void forwardSelect(int sid, Session session, int eid, REPNode editor) { REPNode next; // session searching continue... @@ -241,11 +219,16 @@ /* * Create and send UPDATE command. */ - private void sendUpdate(int sid) { + public void sendUpdate(int sid) { REPCommand command = makeREPCommandWithSessionList(REP.SMCMD_UPDATE); command.setSID(sid); command.setEID(REP.SM_EID.id); - smList.sendToMaster(command); + if (isMaster()) { + command.setCMD(REP.SMCMD_UPDATE_ACK); + smList.sendToSlaves(command); + } else { + smList.sendToMaster(command); + } } /* @@ -403,7 +386,7 @@ // shared among sessions. REPNode f = createSessionForwarder(command.sid, forwarder); session.addForwarder(f); // f.next is set up here. - selectSession(command.sid, session, command.eid, forwarder); + forwarder.selectSession(command,session); } break; case SMCMD_SELECT_ACK: @@ -435,20 +418,17 @@ } } break; - + + case SMCMD_SYNC_ACK: + break; + case SMCMD_SM_JOIN_ACK: send_sm_join_ack(command.eid, command.sid, command); break; case SMCMD_UPDATE: - if (!isMaster()) { - command.setString(mergeUpdate(command)); - // 上に知らせる - smList.sendToMaster(command); - break; - } - // fall thru - command.setCMD(REP.SMCMD_UPDATE_ACK); + sendUpdate(command.sid); + break; case SMCMD_UPDATE_ACK: command.setString(mergeUpdate(command)); // 下に知らせる @@ -506,6 +486,12 @@ // select したeditor を見つけた command.cmd=REP.SMCMD_JOIN_ACK; editor.send(command); + sendUpdate(command.sid); + if (sync) { + REPCommand sync = new REPCommand(command); + sync.setCMD(REP.SMCMD_SYNC); + editor.sendSync(sync); + } return; } } diff -r 1fca50ce3508 -r bba62c4ac323 rep/handler/Dispatcher.java --- a/rep/handler/Dispatcher.java Mon Nov 10 22:18:14 2008 +0900 +++ b/rep/handler/Dispatcher.java Mon Nov 10 22:19:34 2008 +0900 @@ -2,7 +2,6 @@ import java.io.IOException; -import rep.PacketSet; import rep.REPCommand; import rep.ServerMainLoop; import rep.Session; @@ -77,11 +76,5 @@ return false; } - @Override - public void send(REPCommand command) { - assert(command!=null); - assert(channel!=null); - REPCommand c = new REPCommand(command); - manager.addWriteQueue(new PacketSet(channel,null, c)); - } + } diff -r 1fca50ce3508 -r bba62c4ac323 rep/handler/Editor.java --- a/rep/handler/Editor.java Mon Nov 10 22:18:14 2008 +0900 +++ b/rep/handler/Editor.java Mon Nov 10 22:19:34 2008 +0900 @@ -171,6 +171,13 @@ } break; } + + case SMCMD_SYNC: + if (isMaster()) + send(receivedCommand); + else + next.send(receivedCommand); + case SMCMD_QUIT: { next.send(receivedCommand); @@ -222,6 +229,7 @@ public boolean isMaster() { return mode==REP.SMCMD_PUT; } + /* Handle special case first, usually these cases * are handled in the next Editor in a session manager, but @@ -247,11 +255,4 @@ send(command); } - @Override - public void send(REPCommand command) { - assert(command!=null); - assert(channel!=null); - REPCommand c = new REPCommand(command); - manager.addWriteQueue(new PacketSet(channel,null, c)); - } } diff -r 1fca50ce3508 -r bba62c4ac323 rep/handler/Forwarder.java --- a/rep/handler/Forwarder.java Mon Nov 10 22:18:14 2008 +0900 +++ b/rep/handler/Forwarder.java Mon Nov 10 22:19:34 2008 +0900 @@ -5,6 +5,7 @@ import rep.PacketSet; import rep.REP; import rep.REPCommand; +import rep.Session; import rep.SessionManager; import rep.channel.REPLogger; import rep.channel.REPSelectionKey; @@ -93,5 +94,35 @@ return false; } + public void selectSession(REPCommand sendCommand,Session session) { + if(session.hasOwner()){ + // we have a selected session. + if (isDirect()&&getEID()==sendCommand.eid) { + // Found directly connected joined editor. Send join_ack(). + // we have one more point to send JOIN_ACK to the editor. + session.addForwarder(this); + manager.sendUpdate(session.getSID()); + sendCommand.setCMD(REP.SMCMD_JOIN_ACK); + if (manager.sync) { + REPCommand sync = new REPCommand(sendCommand); + sync.setCMD(REP.SMCMD_SYNC); + sendSync(sync); + } + } else { + // We have a session, but joined editor is on the other sm. + // SELECT_ACK is sent to the session ring to + // find out the joined editor. + sendCommand.setCMD(REP.SMCMD_SELECT_ACK); + } + sendCommand.string = session.getName(); + send(sendCommand); + }else { + manager.forwardSelect(sid, session, eid, this); + } + } + + + + } \ No newline at end of file diff -r 1fca50ce3508 -r bba62c4ac323 rep/handler/REPNode.java --- a/rep/handler/REPNode.java Mon Nov 10 22:18:14 2008 +0900 +++ b/rep/handler/REPNode.java Mon Nov 10 22:19:34 2008 +0900 @@ -4,6 +4,7 @@ import rep.REP; import rep.REPCommand; +import rep.Session; import rep.channel.REPSelectionKey; import rep.channel.REPSocketChannel; @@ -103,6 +104,7 @@ public abstract void send(REPCommand command) ; + public abstract void sendWithSeq(REPCommand command) ; public abstract void setQuit2(REPCommand receivedCommand) ; @@ -114,6 +116,8 @@ public abstract boolean manage(REPCommand command) ; + public abstract void selectSession(REPCommand sendCommand,Session session) ; + public void setMode(REP cmd) { mode = cmd; } @@ -136,6 +140,10 @@ public void setNext(REPNode f) { next = f; } - + + public void sendSync(REPCommand sync) { + next.sendWithSeq(sync); + } + } diff -r 1fca50ce3508 -r bba62c4ac323 rep/xml/SessionXMLDecoder.java --- a/rep/xml/SessionXMLDecoder.java Mon Nov 10 22:18:14 2008 +0900 +++ b/rep/xml/SessionXMLDecoder.java Mon Nov 10 22:19:34 2008 +0900 @@ -9,6 +9,8 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -22,15 +24,13 @@ DocumentBuilderFactory factory; DocumentBuilder builder; - public SessionXMLDecoder(String string) throws SAXException, IOException { - decode(string); - } public SessionXMLDecoder() { factory = DocumentBuilderFactory.newInstance(); try { - factory.newDocumentBuilder(); + builder = factory.newDocumentBuilder(); } catch (ParserConfigurationException e) { + assert false; } } @@ -65,9 +65,9 @@ SessionList sessionlist = new SessionList(); NodeList nodelistSession = element.getElementsByTagName("Session"); for(int i = 0; i < nodelistSession.getLength(); i++){ - Element elementSession = (Element) nodelistSession.item(i); - int sid = Integer.parseInt(elementSession.getAttribute("sid")); - NodeList nodelistEditor = elementSession.getElementsByTagName("Editor"); + Node elementSession = nodelistSession.item(i); + int sid = getIntValue(elementSession,"sid"); + NodeList nodelistEditor = ((Element)elementSession).getElementsByTagName("Editor"); Session session = null; for(int j = 0; j < nodelistEditor.getLength(); j++){ @@ -76,7 +76,8 @@ Element elementEditor = (Element) nodelistEditor.item(j); NodeList nodelistEditorHost = elementEditor.getElementsByTagName("host"); Element elementHost = (Element) nodelistEditorHost.item(0); - String host = elementHost.getFirstChild().getNodeValue(); + Node hostValue = elementHost.getFirstChild(); + String host = hostValue==null?"":hostValue.getNodeValue(); if(elementEditor.getChildNodes().getLength() > 2){ NodeList nodelistEditorFile = elementEditor.getElementsByTagName("file"); @@ -100,5 +101,18 @@ } return sessionlist; } + + private int getIntValue(Node elementSession, String attrName) { + NamedNodeMap attr = elementSession.getAttributes(); + Node sidNode = attr.getNamedItem(attrName); + int sid = Integer.parseInt(sidNode.getNodeValue()); + return sid; + } +// +// private String getString(Node elementSession, String attrName) { +// NamedNodeMap attr = elementSession.getAttributes(); +// Node sidNode = attr.getNamedItem(attrName); +// return sidNode.getNodeValue(); +// } } diff -r 1fca50ce3508 -r bba62c4ac323 test/Text.java --- a/test/Text.java Mon Nov 10 22:18:14 2008 +0900 +++ b/test/Text.java Mon Nov 10 22:19:34 2008 +0900 @@ -28,13 +28,13 @@ return strList.remove(i); } public String replace(int i, String str){ - assert 0cmdList = new LinkedList(); String[] txts = { - "aaa", "bbb", "ccc", "ddd", "eee", + "aaa", "bbb", // "ccc", "ddd", "eee", }; port = _port; semaIP = new InetSocketAddress(_host, _port); @@ -82,6 +82,8 @@ if (master) { this.master=true; text = new Text(txts); + } else { + text = new Text(new String[0]); } } @@ -195,8 +197,9 @@ assert(false); } } else { - // no more command to send - timeout = 0; + if(syncCounter==0) + // no more command to send, and we don't have syncCounter + timeout = 0; } } @@ -300,8 +303,11 @@ // start contents sync with newly joined editor cmd.cmd = REP.SMCMD_SYNC_ACK; forwardCommand(cmd); - if (cmd.eid==eid) + //if (cmd.eid==eid) { + if (master) { syncCounter = 1; + timeout = 1; + } break; default: assert(false);