changeset 411:795ef563f2a0

add commnets
author one
date Wed, 26 Nov 2008 09:41:14 +0900
parents 2724cf17e9f3
children 2c815dd5f797
files Todo rep/ServerMainLoop.java rep/Session.java rep/SessionManagerList.java rep/handler/Editor.java rep/handler/Translator.java test/sematest/TestEditor.java test/sematest/TestInterManagerSession.java
diffstat 8 files changed, 117 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/Todo	Tue Nov 25 18:26:23 2008 +0900
+++ b/Todo	Wed Nov 26 09:41:14 2008 +0900
@@ -1,3 +1,9 @@
+Wed Nov 26 08:44:29 JST 2008
+
+Todo:
+QUITで、まだ、処理があるのにEditorが止まってしまう状況が
+あるらしい。
+
 Tue Nov 25 09:13:42 JST 2008
 
 Todo: 
@@ -5,6 +11,9 @@
 どうも、optimizerのbugっぽいな... いや、違いますね。
 getMergeAgainの問題らしいが、直接の原因は良くわからない。
 
+Done:
+   なんと、Text.javaのdeleteの条件判断が間違ってました。
+
 Mon Nov 24 22:51:45 JST 2008
 
 watingCommandInMerge のqueueを一旦0にしてから、manageを
--- a/rep/ServerMainLoop.java	Tue Nov 25 18:26:23 2008 +0900
+++ b/rep/ServerMainLoop.java	Wed Nov 26 09:41:14 2008 +0900
@@ -21,6 +21,13 @@
 import rep.handler.FirstConnector;
 import rep.handler.REPNode;
 
+/**
+ * @author kono
+ *  Single Threaded Server Main Loop
+ *    maintain multiple connections
+ *    gui interface is provided.
+ *  Protocols are handled by our manager.
+ */
 public class ServerMainLoop  {
 
 	public static REPLogger logger = REPLogger.singleton();
@@ -35,6 +42,7 @@
 	protected int parent_port;
 	protected static final int DEFAULT_PORT = 8766;
 	private SessionManagerEvent execAfterConnect = null;
+	private boolean listLocalEditorOnly = false;
 
 
 	public void setReceivePort(int port) {
@@ -90,6 +98,12 @@
 		return false;
 	}
 
+	/**
+	 * To avoid dead locks, we write a command one at a time
+	 * during select().
+	 * @return
+	 * @throws IOException
+	 */
 	private boolean checkWaitingWrite() throws IOException {
 		PacketSet p = writeQueue.poll();
 		if (p!=null) {
@@ -100,6 +114,10 @@
 		return false;
 	}
 
+	/**
+	 * Debug message
+	 * @param p
+	 */
 	private void sendLog(PacketSet p) {
 		REPNode to;
 		String s;
@@ -120,6 +138,13 @@
 		// we have to remove session/editor
 	}
 
+	/**
+	 * Main Select routing
+	 *     check incoming connection request and incoming packet
+	 *     A request is handled by a handler object which is attached
+	 *     to the SelectionKey.  
+	 * @throws IOException
+	 */
 	private void select() throws IOException {
 		
 		Set<REPSelectionKey<REPCommand>> keys = selector.selectedKeys1();
@@ -159,12 +184,17 @@
 		channel.register(selector, SelectionKey.OP_READ, handler);
 	}
 
+	/**
+	 *   Notify status change to our GUI
+	 */
 	protected void updateGUI() {
 		//リストのコピーをGUIに渡す
 		LinkedList<Session> sList = new LinkedList<Session>(manager.sessionList.values());
 		LinkedList<REPNode> eList;
-		if (false) { 
-			// local editor only 
+		if (listLocalEditorOnly ) { 
+			// Do not list an editor or session outside of this session manager to
+			// avoid confusion. Actually we can joinSession to an editor outside of
+			// this manager, but is not secure to do this.
 			eList = new LinkedList<REPNode>();
 			for(REPNode e:manager.editorList.values()) {
 				if (manager.getSMID(e.eid)==manager.smList.sessionManagerID()) {
--- a/rep/Session.java	Tue Nov 25 18:26:23 2008 +0900
+++ b/rep/Session.java	Wed Nov 26 09:41:14 2008 +0900
@@ -10,13 +10,22 @@
 
 public class Session extends HashMap<Integer,REPNode> {
 	/**
-	 * 
+	 * Editor Session
+	 *    contains interacting editors
+	 *    accessed by eid. There is one masterEditor which
+	 *    has a file name (is a sessionName).
+	 *    
+	 *    maintain connection among handlers (Dispatcher,
+	 *    Forwarder, Editor).
+	 *       first->editor->editor...->last
+	 *    first may equal to the last. When a session is
+	 *    created, first equals the last.   
 	 */
 	private static final long serialVersionUID = 1L;
 	private REPNode masterEditor;
 	private int sessionID;
 	private String sessionName;
-	// isOnwer means this session has active channels(forwarders).
+	// isOnwer means this session is owner of an active channels(forwarders).
 	private boolean isOwner = false;
 	private REPNode first;
 	private REPNode last;
@@ -35,6 +44,7 @@
 			master.setSID(sid);
 			put(master.eid,master);
 			if(master.channel!=null) {
+				// master is a real connected editor
 				first = master;
 				masterEditor.setNext(masterEditor);
 				isOwner = true;
@@ -60,7 +70,7 @@
 	
 	public void addEditor(Editor editor) {
 		// add a not-connected editor in a sassion
-		// the editor is outside of this manager 
+		// the editor is in the outside of this manager 
 		editor.setSID(sessionID);
 		put(editor.eid,editor);
 	}
@@ -79,12 +89,19 @@
 		return sessionName;
 	}
 	
-	
+	/*
+	 * Remove and disconnect a forwarder from the session
+	 */
 	public boolean deleteEditor(REPSocketChannel<REPCommand> channel) {
+		// this is fanatic, one channel may have multiple sessions, but
+		// a session should have only one channel that is one editor.
+		//  REPNode e = getEditor(channel);
+		//  if (e!=null) { unconnect((Forwarder)e); remove(e); } is Ok.
 		LinkedList<REPNode> toBeRemoved = new LinkedList<REPNode>();
 	    for (REPNode e:values() ) {
 			if (e.getChannel()==channel) {
 				unconnect((Forwarder)e);
+				// we cannot directly remove this because of the concurrent access
 				toBeRemoved.add(e);
 			}
 		}
@@ -99,6 +116,10 @@
 		return remove(editor)!=null;
 	}
 	
+	/*
+	 * Clear connection of a forwarder. The rest of the forwarders in this
+	 * session have to be connected properly.
+	 */
 	private void unconnect(Forwarder e) {
 		boolean hasOwner = false;
 		for(REPNode e1:values()) {
@@ -134,6 +155,10 @@
 
 	
 	
+	/**
+	 * Start closing protocol
+	 *    not yet implemented. Use quit instead.
+	 */
 	public void closeSession() {
 		REPNode f = first;
 		if (f!=null) {
@@ -150,6 +175,11 @@
 	}
 
 
+	/**
+	 * @param manager
+	 * 
+	 * remove all editors in this session from our manager. 
+	 */
 	public void remove(SessionManager manager) {
 		for(REPNode editor : values()){
 			if(editor.getChannel() !=null) 
@@ -159,12 +189,19 @@
 	}
 
 
+	/**
+	 * @param s
+	 * 
+	 * Merge editors from UPDATED session. Only dummy editors
+	 * outside of this manager to be add.
+	 */
 	public void merge(Session s) {
 		for(REPNode editor : s.values()){
 			REPNode mine = get(editor.eid);
 			if (mine==null) {
 				put(editor.eid,editor);
 			} else {
+				// update editor status
 				mine.merge(editor);
 			}
 		}	
--- a/rep/SessionManagerList.java	Tue Nov 25 18:26:23 2008 +0900
+++ b/rep/SessionManagerList.java	Wed Nov 26 09:41:14 2008 +0900
@@ -9,7 +9,7 @@
 public class SessionManagerList extends LinkedList<REPNode>{
 
 	/**
-	 * 
+	 * Session Manager List which we have a connection.
 	 */
 	private static final long serialVersionUID = 1L;
 	private int mySMID=0;
@@ -36,6 +36,16 @@
 		return !parent.isForwarder();
 	}
 
+	/**
+	 * Add our slave session manager. Only an empty session manager can
+	 * connect to the other session manager. join_sm() is forwarded to
+	 * the master session manager, and in the master addNewSessionManager()
+	 * is performed.
+	 * 
+	 * @param sm
+	 * @param receivedCommand
+	 * @return session manager id (global)
+	 */
 	public int addNewSessionManager(REPNode sm,REPCommand receivedCommand) {
 		add(sm);
 		int sid = ++smid_root;
@@ -53,12 +63,22 @@
 		return mySMID;
 	}
 
+	/**
+	 * An sm_join() is accepted, but we are not the master, forward request
+	 * and register as an waiting sessin manager.
+	 * @param fw
+	 * @param command
+	 */
 	public void addWaitingSessionManager(REPNode fw, REPCommand command) {
 		// SID assign 待ちのSessionManager Channelを登録する
 		waiting.add(fw);
 		
 	}
 
+	/**
+	 * An sm_join_ack() is received. Assign session manager id to the waiter.
+	 * @param sid
+	 */
 	public void assignSessionManagerIDtoWaitingSM(int sid) {
 		// 待っていたSession Manager ChannelにSession IDを登録し,Session Manager List
 		// に登録する。この次のsm_join_ackでSIDが確定する。
--- a/rep/handler/Editor.java	Tue Nov 25 18:26:23 2008 +0900
+++ b/rep/handler/Editor.java	Wed Nov 26 09:41:14 2008 +0900
@@ -23,7 +23,7 @@
 	private boolean merging;
 	private REPCommand preMergeCommand;
 	public static boolean noMergeMode=false;
-	static final boolean doOptimize = false;
+	static final boolean doOptimize = true;
 
 	public Editor(SessionManager manager,int editorNo){
 		// no translator case
--- a/rep/handler/Translator.java	Tue Nov 25 18:26:23 2008 +0900
+++ b/rep/handler/Translator.java	Wed Nov 26 09:41:14 2008 +0900
@@ -195,16 +195,16 @@
 				returnCommand.add(command);
 			}
 		}
-		int count = 0;
-		for(REPCommand command: returnCommand) {
-			switch(command.cmd) {
-			case REPCMD_INSERT: count++; break;
-			case REPCMD_DELETE: count--; break;
-			default: assert false;
-			}
-		}
-		SessionManager.logger.writeLog("MergeAgain ret="+returnCommand.size()+
-				" increment="+count);
+//		int count = 0;
+//		for(REPCommand command: returnCommand) {
+//			switch(command.cmd) {
+//			case REPCMD_INSERT: count++; break;
+//			case REPCMD_DELETE: count--; break;
+//			default: assert false;
+//			}
+//		}
+		SessionManager.logger.writeLog("MergeAgain ret="+returnCommand.size());
+//				+" increment="+count);
 		mergeAgainList.clear();
 		optimizedSend(editor, returnCommand);
 	}
--- a/test/sematest/TestEditor.java	Tue Nov 25 18:26:23 2008 +0900
+++ b/test/sematest/TestEditor.java	Wed Nov 26 09:41:14 2008 +0900
@@ -18,7 +18,7 @@
 
 /**
  * @author kono
- *	Basic Temote Editor client implementation
+ *	Basic Remote Editor client implementation
  *     should support multi-session
  *     currently multi-session requires new channel, that is
  *     only one session for this editor.
@@ -69,7 +69,6 @@
 			text = new Text(new String[0]);
 			cmds.add(new REPCommand(REP.SMCMD_JOIN,0,0,0,0,name));
 			cmds.add(new REPCommand(REP.REPCMD_INSERT_USER,0,0,0,0,"c0"));
-			
 			cmds.add(new REPCommand(REP.REPCMD_DELETE_USER,0,0,0,0,"c0"));
 		}
 	}
@@ -154,6 +153,7 @@
 			SessionManager.logger.writeLog("Sync Completed.");
 			syncCounter=0;
 		} else {
+			if (inputLock) return;
 			int i=syncCounter-1;
 			REPCommand del = new REPCommand(REP.REPCMD_DELETE_USER,sid,eid,0,i, text.get(i));
 			REPCommand ins = new REPCommand(REP.REPCMD_INSERT_USER,sid,eid,0,i, text.get(i));
--- a/test/sematest/TestInterManagerSession.java	Tue Nov 25 18:26:23 2008 +0900
+++ b/test/sematest/TestInterManagerSession.java	Wed Nov 26 09:41:14 2008 +0900
@@ -121,6 +121,7 @@
 		cmds.add(new REPCommand(REP.SMCMD_PUT,0,0,0,0,"Editor0-file"));
 		cmds.add(new REPCommand(REP.REPCMD_INSERT_USER,0,0,0,0,"m0"));
 		cmds.add(new REPCommand(REP.REPCMD_DELETE_USER,0,0,0,0,"m0"));
+		cmds.add(new REPCommand(REP.SMCMD_QUIT,0,0,0,0,""));
 		editorStartCmds = cmds;
 		LinkedList<REPCommand>nullcmds = new LinkedList<REPCommand>();
 		editors[0].setCommand(nullcmds);