Mercurial > hg > RemoteEditor > REPSessionManager
annotate rep/SessionManager.java @ 382:4b87f89b3afd
REP Session Manager (Java version)
new structure
author | one@firefly.cr.ie.u-ryukyu.ac.jp |
---|---|
date | Mon, 10 Nov 2008 22:07:45 +0900 |
parents | c78569ab5fce |
children | bcdf5476b8e4 |
rev | line source |
---|---|
266 | 1 |
0 | 2 package rep; |
3 | |
4 import java.io.IOException; | |
5 import java.net.InetSocketAddress; | |
267 | 6 import java.nio.channels.ClosedChannelException; |
0 | 7 import java.nio.channels.SelectionKey; |
83 | 8 import java.util.LinkedList; |
144 | 9 import java.util.List; |
231 | 10 import java.util.Set; |
178 | 11 import java.util.concurrent.BlockingQueue; |
192 | 12 import java.util.concurrent.LinkedBlockingQueue; |
0 | 13 |
346 | 14 import org.xml.sax.SAXException; |
15 | |
198 | 16 |
353 | 17 |
337 | 18 import rep.channel.REPLogger; |
123 | 19 import rep.channel.REPServerSocketChannel; |
133 | 20 import rep.channel.REPSocketChannel; |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
21 import rep.gui.CloseButtonEvent; |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
22 import rep.gui.DoGUIUpdate; |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
23 import rep.gui.SelectButtonEvent; |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
24 import rep.gui.SessionManagerEvent; |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
25 import rep.gui.SessionManagerEventListener; |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
26 import rep.gui.SessionManagerGUI; |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
27 import rep.gui.SessionManagerGUIimpl; |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
28 import rep.handler.Dispatcher; |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
29 import rep.handler.Editor; |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
30 import rep.handler.REPNode; |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
31 import rep.handler.FirstConnector; |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
32 import rep.handler.Forwarder; |
158 | 33 import rep.channel.REPSelector; |
56 | 34 import rep.xml.SessionXMLDecoder; |
45 | 35 import rep.xml.SessionXMLEncoder; |
198 | 36 import rep.channel.REPSelectionKey; |
264 | 37 |
198 | 38 /* |
264 | 39 +-------+--------+--------+-------+--------+---------+------+ |
40 | cmd | session| editor | seqid | lineno | textsiz | text | | |
41 | | id | id | | | | | | |
42 +-------+--------+--------+-------+--------+---------+------+ | |
43 o---------- header section (network order) ----------o | |
44 | |
45 int cmd; kind of command | |
46 int sid; session ID : uniqu to editing file | |
47 int eid; editor ID : owner editor ID = 1。Session に対して unique | |
308 | 48 -1 session manager command |
49 -2 merge command | |
264 | 50 int seqno; Sequence number : sequence number はエディタごとに管理 |
51 int lineno; line number | |
52 int textsize; textsize : bytesize | |
53 byte[] text; | |
198 | 54 */ |
1 | 55 |
250 | 56 public class SessionManager implements SessionManagerEventListener{ |
337 | 57 static public REPLogger logger = REPLogger.singleton(); |
58 | |
363 | 59 SessionList sessionList; |
280 | 60 private SessionManagerGUI gui; |
363 | 61 // Main nio.Selector of this server |
198 | 62 private REPSelector<REPCommand> selector; |
363 | 63 // Known Session Manager List, At most one parent. No parent means master. |
319 | 64 SessionManagerList smList; |
363 | 65 // Known Editor list. Connected Editor has a channel. |
66 // Session Manager Channel may have dummy editors. | |
356 | 67 EditorList editorList; |
363 | 68 // Commands for busy editor are kept in this queue. |
212 | 69 private List<PacketSet> waitingCommandInMerge; |
363 | 70 // Command from gui. Synchronization is required. |
71 private BlockingQueue<SessionManagerEvent> waitingEventQueue | |
72 = new LinkedBlockingQueue<SessionManagerEvent>();; | |
73 // host name of this server. One of connecting SocketChannel's hostname | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
74 public String myHost; |
363 | 75 // Single threaded write queueu. To avoid dead lock with too many writes. |
317 | 76 private LinkedList<PacketSet> writeQueue = new LinkedList<PacketSet>(); |
336 | 77 private int receive_port; |
78 private int parent_port; | |
101 | 79 static final int DEFAULT_PORT = 8766; |
363 | 80 // Queue limit for debugging purpose. |
332 | 81 private static final int packetLimit = 200; |
358 | 82 |
363 | 83 // globalSessionID = SessionManagerID * MAXID + localSessionID |
358 | 84 private static final int MAXID = 10000; |
353 | 85 SessionXMLDecoder decoder = new SessionXMLDecoder(); |
358 | 86 SessionXMLEncoder encoder = new SessionXMLEncoder(); |
363 | 87 // SocketChannel for our parent. At most one parent is allowed. |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
88 private REPNode sm_join_channel; |
363 | 89 // Routing table for session and session manager. |
369 | 90 private RoutingTable routingTable = new RoutingTable(this); |
365
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
91 private SessionManagerEvent execAfterConnect = null;; |
358 | 92 |
316 | 93 public static void main(String[] args) throws InterruptedException, IOException { |
94 | |
95 int port = DEFAULT_PORT; | |
96 int port_s = DEFAULT_PORT; | |
97 //System.setProperty("file.encoding", "UTF-8"); | |
98 if(args.length > 0){ | |
363 | 99 if (args.length!=2) { |
100 logger.writeLog("Usage: sessionManager our_port parent_port"); | |
101 return; | |
102 } | |
316 | 103 port = Integer.parseInt(args[0]); |
104 port_s = Integer.parseInt(args[1]); | |
105 } | |
106 SessionManager sm = new SessionManager(); | |
336 | 107 sm.setReceivePort(port); |
108 sm.setParentPort(port_s); | |
363 | 109 // Ok start main loop |
316 | 110 sm.init(port,new SessionManagerGUIimpl(sm)); |
111 } | |
112 | |
336 | 113 public void setReceivePort(int port) { |
114 receive_port = port; | |
115 } | |
116 | |
280 | 117 public void init(int port, SessionManagerGUI gui) throws IOException, InterruptedException { |
118 this.gui = gui; | |
119 init(port); | |
120 mainLoop(); | |
121 } | |
122 | |
123 private void init(int port) throws InterruptedException, IOException { | |
363 | 124 selector = REPSelector.<REPCommand>create(); |
186 | 125 REPServerSocketChannel<REPCommand> ssc = REPServerSocketChannel.<REPCommand>open(new REPCommandPacker()); |
363 | 126 ssc.configureBlocking(false); // Selector requires this |
127 ssc.socket().setReuseAddress(true); //reuse address 必須 | |
212 | 128 //getAllByNameで取れた全てのアドレスに対してbindする |
129 ssc.socket().bind(new InetSocketAddress(port)); | |
349 | 130 ssc.register(selector, SelectionKey.OP_ACCEPT, |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
131 new Dispatcher(this)); // FirstConnector? |
6 | 132 |
358 | 133 sessionList = new SessionList(); |
7 | 134 smList = new SessionManagerList(); |
356 | 135 editorList = new EditorList(); |
212 | 136 waitingCommandInMerge = new LinkedList<PacketSet>(); |
228 | 137 |
215 | 138 |
155 | 139 } |
313 | 140 |
141 /* | |
363 | 142 * The main loop. |
143 * Check incoming events and waiting writes. | |
144 * Do select and call select() to check in coming packets. | |
313 | 145 * We wrote everything in one thread, but we can assign |
146 * one thread for each communication channel and GUI event. | |
147 */ | |
231 | 148 public void mainLoop() throws IOException { |
0 | 149 while(true){ |
328 | 150 checkWaitingCommandInMerge(); |
313 | 151 if (checkInputEvent() || |
328 | 152 checkWaitingWrite()) { |
313 | 153 // try to do fair execution for waiting task |
154 if(selector.selectNow() > 0) select(); | |
155 continue; | |
300 | 156 } |
313 | 157 // now we can wait for input packet or event |
233 | 158 selector.select(); |
144 | 159 select(); |
160 } | |
161 } | |
162 | |
363 | 163 /* |
164 * Synchronize GUI event in the main loop. | |
165 */ | |
313 | 166 private boolean checkInputEvent() { |
167 SessionManagerEvent e; | |
168 if((e = waitingEventQueue.poll())!=null){ | |
334 | 169 e.exec(this); |
313 | 170 return true; |
171 } | |
172 return false; | |
173 } | |
174 | |
363 | 175 /* |
176 * Write a packet during the main loop. | |
177 */ | |
313 | 178 private boolean checkWaitingWrite() throws IOException { |
317 | 179 PacketSet p = writeQueue.poll(); |
180 if (p!=null) { | |
327 | 181 p.channel.write(p.command); |
317 | 182 return true; |
313 | 183 } |
184 return false; | |
185 } | |
186 | |
308 | 187 /** |
188 * Check waiting command in merge | |
189 * @return true if there is a processed waiting command | |
190 * @throws IOException | |
191 */ | |
346 | 192 private void checkWaitingCommandInMerge() { |
328 | 193 List<PacketSet> w = waitingCommandInMerge; |
194 waitingCommandInMerge = new LinkedList<PacketSet>(); | |
195 for(PacketSet p: w) { | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
196 REPNode e = p.getEditor(); |
353 | 197 if(e.isMerging()) { // still merging do nothing |
328 | 198 waitingCommandInMerge.add(p); |
199 } else { | |
346 | 200 try { |
353 | 201 if (sessionManage(e, p.command)) { // we don't need this |
202 assert false; | |
203 return; | |
204 } | |
205 e.manage(p.command); | |
347 | 206 } catch (Exception e1) { |
349 | 207 // should be e.close()? |
346 | 208 close(p.channel); |
209 } | |
328 | 210 } |
211 } | |
212 } | |
363 | 213 |
214 /* | |
215 * If we have waiting write commands, further sent commands also | |
216 * wait to avoid out of order packet sending. | |
217 */ | |
218 public boolean hasWaitingCommand(REPSocketChannel<REPCommand>c) { | |
219 for(PacketSet p:waitingCommandInMerge) { | |
220 if (p.channel==c) { | |
221 return true; | |
222 } | |
223 } | |
224 return false; | |
225 } | |
328 | 226 |
363 | 227 /* |
228 * Close a channel in case of exception or close. | |
229 */ | |
346 | 230 private void close(REPSocketChannel<REPCommand> channel) { |
231 REPSelectionKey<REPCommand>key = channel.keyFor1(selector); | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
232 REPNode handler = (REPNode)key.attachment(); |
346 | 233 key.cancel(); |
234 handler.cancel(channel); | |
235 // we have to remove session/enditor | |
236 } | |
237 | |
238 | |
363 | 239 /* |
240 * Do select operation on the Selector. Each key has a forwarder. | |
241 * A forwarder can be a firstConnector, a forwarder for Session Manager | |
242 * or an Editor. | |
243 */ | |
144 | 244 private void select() throws IOException { |
231 | 245 |
246 Set<REPSelectionKey<REPCommand>> keys = selector.selectedKeys1(); | |
247 for(REPSelectionKey<REPCommand> key : keys){ | |
144 | 248 if(key.isAcceptable()){ |
363 | 249 /* |
250 * Incoming connection. We don't know which, editor or | |
251 * session manager. Assign FirstConnector to distinguish. | |
252 */ | |
199 | 253 REPSocketChannel<REPCommand> channel = key.accept(new REPCommandPacker()); |
337 | 254 logger.writeLog("SessionManager.select() : key.isAcceptable : channel = " + channel); |
363 | 255 registerChannel(channel, new FirstConnector(this)); |
144 | 256 channel = null; |
257 }else if(key.isReadable()){ | |
363 | 258 /* |
259 * Incoming packets are handled by a various forwarder. | |
260 * A hadler throw IOException() in case of a trouble to | |
261 * close the channel. | |
262 */ | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
263 REPNode handler = (REPNode)key.attachment(); |
267 | 264 try { |
265 handler.handle(key); | |
358 | 266 } catch (IOException e) { |
267 | 267 key.cancel(); |
308 | 268 handler.cancel(key.channel1()); |
267 | 269 } |
0 | 270 } |
271 } | |
272 } | |
1 | 273 |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
274 public void registerChannel(REPSocketChannel<REPCommand> channel,REPNode handler) throws IOException { |
2 | 275 if(channel == null) { |
276 return; | |
277 } | |
349 | 278 handler.setChannel(channel); |
2 | 279 channel.configureBlocking(false); |
355 | 280 channel.register(selector, SelectionKey.OP_READ, handler); |
2 | 281 } |
282 | |
363 | 283 /* |
284 * After loop detection, we give up session manager join. | |
285 */ | |
286 private void cancel_sm_join() { | |
364 | 287 logger.writeLog("Loop detected "+this); |
355 | 288 removeChannel(sm_join_channel); |
289 sm_join_channel=null; | |
290 } | |
291 | |
292 | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
293 private void removeChannel(REPNode channel) { |
363 | 294 REPSelectionKey<REPCommand> key = channel.channel.keyFor1(selector); |
355 | 295 key.cancel(); |
296 try { | |
364 | 297 channel.channel.close1(); |
355 | 298 } catch (IOException e) { |
299 } | |
349 | 300 } |
301 | |
320 | 302 |
319 | 303 void updateGUI() { |
212 | 304 //リストのコピーをGUIに渡す |
358 | 305 LinkedList<Session> sList = new LinkedList<Session>(sessionList.values()); |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
306 LinkedList<REPNode> eList; |
365
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
307 if (false) { |
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
308 // local editor only |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
309 eList = new LinkedList<REPNode>(); |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
310 for(REPNode e:editorList.values()) { |
365
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
311 if (getSMID(e.eid)==smList.sessionManagerID()) { |
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
312 eList.add(e); |
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
313 } |
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
314 } |
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
315 } else { |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
316 eList = new LinkedList<REPNode>(editorList.values()); |
365
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
317 } |
212 | 318 //GUIに反映 |
319 Runnable doRun = new DoGUIUpdate(sList, eList, gui); | |
279 | 320 gui.invokeLater(doRun); |
212 | 321 } |
322 | |
83 | 323 |
139 | 324 |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
325 public void setMyHostName(String localHostName) { |
308 | 326 myHost = localHostName + receive_port; |
164 | 327 setHostToEditor(myHost); |
328 } | |
329 | |
330 private void setHostToEditor(String myHost2) { | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
331 for(REPNode editor : editorList.values()){ |
358 | 332 if (editor.channel!=null) |
333 editor.setHost(myHost2); | |
164 | 334 } |
76 | 335 } |
0 | 336 |
355 | 337 |
338 /** | |
363 | 339 * GUI から、呼ばれて、Session Managerに接続する。 |
355 | 340 * Host 名のSession Manager に SM_JOIN する。自分は、Session を持っていては |
341 * ならない。複数のSession Managerにjoinすることは出来ない。(NATを実装するまでは)。 | |
342 * @param host | |
343 */ | |
378 | 344 public void connectSessionManager(String host, int port) { |
355 | 345 if (sm_join_channel!=null) return; |
346 if (!sessionList.isEmpty()) return; | |
347 if (!smList.isMaster()) return; | |
363 | 348 /* |
349 * IPv6 対応では、複数のアドレスを取って、それのすべてに接続を試す必要が | |
350 * ある。 | |
351 */ | |
1 | 352 InetSocketAddress addr = new InetSocketAddress(host, port); |
353 try { | |
186 | 354 REPSocketChannel<REPCommand> sessionchannel = REPSocketChannel.<REPCommand>create(new REPCommandPacker()); |
1 | 355 sessionchannel.connect(addr); |
337 | 356 while(!sessionchannel.finishConnect()); |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
357 REPNode sm = new FirstConnector(this); |
355 | 358 registerChannel(sessionchannel, sm); |
349 | 359 sm_join(sm); |
1 | 360 }catch (IOException e) { |
361 } | |
362 } | |
364 | 363 |
378 | 364 public void connectSessionManager(String host) { |
365 connectSessionManager(host,parent_port); | |
364 | 366 } |
77 | 367 |
363 | 368 /** |
369 * channel に SMCMD_SM_JOIN command を送る。 | |
370 * @param channel | |
371 */ | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
372 private void sm_join(REPNode channel){ |
355 | 373 sm_join_channel = channel; |
122 | 374 //SM_JOINコマンドを生成。 |
77 | 375 REPCommand command = new REPCommand(); |
376 command.setCMD(REP.SMCMD_SM_JOIN); | |
349 | 377 command.setEID(-1); // request Parent SessionManagerID |
378 command.setSID(-1); // request SessionManagerID | |
79 | 379 |
122 | 380 //hostnameをセット。 |
349 | 381 setMyHostName(channel.getLocalHostName()); |
82 | 382 |
355 | 383 String string = myHost; |
77 | 384 command.setString(string); |
385 | |
122 | 386 //SM_JOINコマンドを送信。 |
349 | 387 channel.send(command); |
363 | 388 // ack を受け取ったら、SessionManagerのListに追加。ここではやらない。 |
77 | 389 } |
349 | 390 |
361 | 391 /* |
392 * Select Session from Manager button | |
393 * selected editor is joined editor directly connected to this session | |
394 * manager. | |
395 */ | |
316 | 396 public void selectSession(SelectButtonEvent event) throws IOException { |
250 | 397 int sid = event.getSID(); |
358 | 398 Session session = sessionList.get(sid); |
365
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
399 if (session==null) throw new IOException(); |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
400 REPNode editor = event.getEditor(); |
324 | 401 if (editor.hasSession()) return; |
365
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
402 // assert(getSMID(editor.eid)==smList.sessionManagerID()); |
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
403 // assert(editor.channel!=null); |
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
404 editor.setSID(sid); // mark as selected |
372 | 405 selectSession0(sid, session, editor.getEID(), editor); |
406 } | |
407 | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
408 private void selectSession0(int sid, Session session, int eid, REPNode editor) { |
372 | 409 if (editor.isDirect()&&editor.getEID()==eid) { |
410 selectSession(sid, session, editor.getEID(), editor); | |
411 } else { | |
412 // we don't have this editor, search the editor first. | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
413 REPNode next = routingTable.toSessionManager(getSMID(eid)); |
372 | 414 // pass the select command to the next path. |
415 REPCommand command = new REPCommand(); | |
416 command.setCMD(REP.SMCMD_SELECT0); | |
417 command.setSID(sid); | |
418 command.setEID(eid); | |
419 command.setString(editor.getHost()); | |
420 next.send(command); | |
421 } | |
358 | 422 } |
423 | |
361 | 424 /* |
425 * Select Session Protocol handler | |
363 | 426 * called from GUI or incoming SMCMD_SELECT command. |
361 | 427 */ |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
428 private void selectSession(int sid, Session session, int eid, REPNode editor) { |
372 | 429 if(session.hasOwner()){ |
363 | 430 // we have selected session. |
107 | 431 REPCommand sendCommand = new REPCommand(); |
358 | 432 if (editor.isDirect()&&editor.getEID()==eid) { |
363 | 433 // Found directly connected joined editor. Send join_ack(). |
361 | 434 session.addForwarder(editor); |
359
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
435 sendUpdate(session.getSID()); |
358 | 436 sendCommand.setCMD(REP.SMCMD_JOIN_ACK); |
437 } else { | |
363 | 438 // We have a session, but joined editor is on the other sm. |
358 | 439 // SELECT_ACK is sent to the session ring to |
363 | 440 // find out the joined editor. |
358 | 441 sendCommand.setCMD(REP.SMCMD_SELECT_ACK); |
442 } | |
370 | 443 sendCommand.setSID(sid); |
444 sendCommand.string = session.getName(); | |
445 sendCommand.setEID(eid); | |
446 editor.send(sendCommand); | |
107 | 447 }else { |
372 | 448 forwardSelect(sid, session, eid, editor); |
107 | 449 } |
8 | 450 } |
122 | 451 |
372 | 452 private void forwardSelect(int sid, Session session, int eid, |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
453 REPNode editor) { |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
454 REPNode next; |
372 | 455 // session searching continue... |
456 next = routingTable.toSessionManager(getSMID(sid)); | |
457 // make a forwarding channel here | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
458 REPNode f = createSessionForwarder(sid, next); |
372 | 459 session.setFirstForwarder(f); |
460 session.addForwarder(editor); | |
461 // pass the select command to the next path. | |
462 REPCommand command = new REPCommand(); | |
463 command.setCMD(REP.SMCMD_SELECT); | |
464 command.setSID(sid); | |
465 command.setEID(eid); | |
466 command.setString(editor.getHost()); | |
467 next.send(command); | |
468 } | |
469 | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
470 private REPNode createSessionForwarder(int sid, REPNode editor) { |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
471 REPNode f = new Forwarder(this); |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
472 f.setEID(makeID(editorList.newEid())); |
372 | 473 f.setChannel(editor.channel); // incoming channel |
474 f.setHost(myHost); | |
475 f.setSID(sid); | |
476 return f; | |
477 } | |
478 | |
363 | 479 /* |
480 * Create and send UPDATE command. | |
481 */ | |
359
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
482 private void sendUpdate(int sid) { |
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
483 REPCommand command = makeREPCommandWithSessionList(REP.SMCMD_UPDATE); |
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
484 command.setSID(sid); |
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
485 command.setEID(REP.SM_EID.id); |
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
486 smList.sendToMaster(command); |
358 | 487 } |
488 | |
363 | 489 /* |
490 * Create new editor in this sessin manager. A dummy editor | |
491 * is created also. | |
492 */ | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
493 public REPNode newEditor(REPSocketChannel<REPCommand> channel) { |
359
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
494 int eid = makeID(editorList.newEid()); |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
495 REPNode editor = new Editor(this, eid, channel); |
359
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
496 editorList.add(editor); |
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
497 return editor; |
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
498 } |
363 | 499 |
500 /* | |
501 * Create new session. | |
502 */ | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
503 public Session newSession(REPNode master) { |
359
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
504 int sid= makeID(sessionList.newSessionID()); |
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
505 Session session = new Session(sid, master); |
360 | 506 sessionList.put(sid, session); |
359
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
507 return session; |
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
508 } |
358 | 509 |
144 | 510 public void addWaitingCommand(PacketSet set) { |
212 | 511 waitingCommandInMerge.add(set); |
144 | 512 } |
148 | 513 |
363 | 514 /* |
515 * Synchronize GUI command in this session manager. | |
516 */ | |
222 | 517 public void buttonPressed(SessionManagerEvent event) { |
518 try { | |
308 | 519 waitingEventQueue.put(event); |
222 | 520 } catch (InterruptedException e) {} |
521 selector.wakeup(); | |
522 } | |
281 | 523 |
363 | 524 /* |
525 * Execute incoming event during the initialization for | |
526 * testing purpose. | |
527 */ | |
281 | 528 public void syncExec(SessionManagerEvent event) { |
529 try { | |
308 | 530 waitingEventQueue.put(event); |
281 | 531 } catch (InterruptedException e) { |
532 } | |
533 } | |
222 | 534 |
363 | 535 /* |
536 * GUI command interface for close session. | |
537 */ | |
259 | 538 public void closeSession(SessionManagerEvent event) { |
539 Session session = ((CloseButtonEvent) event).getSession(); | |
540 session.closeSession(); | |
541 sessionList.remove(session); | |
542 updateGUI(); | |
543 } | |
544 | |
363 | 545 /* |
546 * Remove editors which has the cannel. | |
547 */ | |
274 | 548 public void remove(REPSocketChannel<REPCommand> channel) { |
358 | 549 int i = 0; |
550 for(Session s:sessionList.values()) { | |
274 | 551 if (s.deleteEditor(channel)) { |
358 | 552 i++; |
274 | 553 } |
554 } | |
358 | 555 assert(i==1); |
274 | 556 // can be other session manager? what should I do? |
557 } | |
558 | |
317 | 559 |
560 public void addWriteQueue(PacketSet packetSet) { | |
324 | 561 writeQueue.addLast(packetSet); |
323 | 562 assert(writeQueue.size()<packetLimit) ; |
317 | 563 } |
564 | |
318 | 565 |
566 public void remove(Editor editor) { | |
358 | 567 Session s = sessionList.get(editor.getSID()); |
362 | 568 if (s==null) { |
569 assert(false); | |
570 editorList.remove(editor); | |
571 } else if (editor.isMaster()) { | |
358 | 572 removeSession(s); |
573 } else { | |
574 s.deleteForwarder(editor); | |
575 editorList.remove(editor); | |
318 | 576 } |
341 | 577 updateGUI(); |
578 } | |
579 | |
580 private void removeSession(Session s0) { | |
358 | 581 s0.remove(this); |
341 | 582 sessionList.remove(s0); |
359
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
583 sendUpdate(s0.getSID()); |
318 | 584 } |
585 | |
334 | 586 public void setParentPort(int port) { |
587 parent_port = port; | |
588 } | |
589 public int getParentPort() { | |
590 return parent_port; | |
591 } | |
592 | |
593 public int getPort() { | |
594 return receive_port; | |
595 } | |
596 | |
353 | 597 |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
598 public boolean sessionManage(REPNode forwarder, REPCommand command) throws ClosedChannelException, |
358 | 599 IOException { |
355 | 600 switch(command.cmd){ |
353 | 601 |
602 // Session Manager Command | |
603 | |
604 case SMCMD_JOIN: | |
605 { | |
358 | 606 // first connection or forwarded command |
367 | 607 routingTable.add(forwarder,getSMID(command.eid)); |
358 | 608 if(isMaster()) { |
609 REPCommand ackCommand = new REPCommand(); | |
610 ackCommand.setCMD(REP.SMCMD_JOIN_ACK); | |
611 ackCommand.setEID(command.eid); | |
360 | 612 ackCommand.setSID(command.sid); |
358 | 613 ackCommand.string = command.string; |
614 smList.sendToSlaves(ackCommand); | |
615 registEditor(forwarder,ackCommand); | |
616 } else { | |
617 smList.sendToMaster(command); | |
618 } | |
360 | 619 updateGUI(); |
353 | 620 } |
621 | |
622 break; | |
623 | |
361 | 624 case SMCMD_PUT_ACK: |
366 | 625 if (forwarder.isDirect()) { |
626 // send put_ack to the editor now. | |
627 command.setCMD(REP.SMCMD_PUT_ACK); | |
628 command.string = command.string; | |
629 command.setEID(command.eid); | |
630 command.setSID(command.sid); | |
631 forwarder.send(command); | |
632 } | |
353 | 633 case SMCMD_JOIN_ACK: |
358 | 634 registEditor(forwarder,command); |
360 | 635 updateGUI(); |
353 | 636 break; |
637 | |
638 case SMCMD_PUT: | |
639 { | |
358 | 640 // first connection or forwarded command |
367 | 641 routingTable.add(forwarder,getSMID(command.eid)); |
370 | 642 REPCommand ack = new REPCommand(command); ack.setCMD(REP.SMCMD_PUT_ACK); |
643 if(isMaster()) { | |
371 | 644 // Reached to the top of the tree, multicast the ack. |
370 | 645 smList.sendToSlaves(ack); |
646 registEditor(forwarder,ack); | |
371 | 647 if (forwarder.isDirect()) { |
648 // If put editor on the master, no SMCMD_PUT_ACK is | |
649 // generated. Send ack to the editor now. | |
650 forwarder.send(ack); | |
651 } | |
358 | 652 } else { |
371 | 653 // Pass this to the master. |
358 | 654 smList.sendToMaster(command); |
361 | 655 // registEditor will be done by SMCMD_PUT_ACK |
656 } | |
360 | 657 updateGUI(); |
353 | 658 |
659 } | |
660 break; | |
358 | 661 |
372 | 662 case SMCMD_SELECT0: |
663 /* | |
664 * finding joining editor, do not make the path. | |
665 */ | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
666 REPNode editor = editorList.get(command.eid); |
372 | 667 if (editor==null|| !editor.isDirect()) { |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
668 REPNode next = routingTable.toSessionManager(getSMID(command.eid)); |
372 | 669 next.send(command); |
670 break; | |
671 } | |
672 // we've found the editor, fall thru. | |
353 | 673 case SMCMD_SELECT: |
361 | 674 { |
372 | 675 /* |
676 * finding active session ring from joined editor. | |
677 */ | |
361 | 678 Session session = sessionList.get(command.sid); |
679 if (session==null) { | |
365
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
680 session = new Session(command.sid, command.string,null); |
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
681 sessionList.put(command.sid,session); |
361 | 682 } |
372 | 683 // Do not directly addForwarder(forwarder). It may be |
684 // shared among sessions. | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
685 REPNode f = createSessionForwarder(command.sid, forwarder); |
372 | 686 session.addForwarder(f); // f.next is set up here. |
361 | 687 selectSession(command.sid, session, command.eid, forwarder); |
688 } | |
689 break; | |
353 | 690 case SMCMD_SELECT_ACK: |
691 { | |
369 | 692 // Sessionが見つかったので、select したeditorに教える。 |
358 | 693 Session session = sessionList.get(command.sid); |
376 | 694 searchSelectedEditor(command,session.getForwarder(forwarder.channel)); |
353 | 695 } |
358 | 696 break; |
697 | |
353 | 698 case SMCMD_SM_JOIN: |
699 { | |
355 | 700 // SM_JOIN中にSMCMD_SM_JOINが来たら、これはループなので、 |
701 ///自分のSM_JOINを取り消す。 | |
702 if (sm_join_channel!=null) cancel_sm_join(); | |
353 | 703 // SMCMD_SM_JOIN は、master まで上昇する。 |
704 // masterでなければ、自分のparentに転送する。 | |
355 | 705 if(isMaster()) { |
353 | 706 // master であれば、SessionManager IDを決めて、 |
707 // 自分のsmList に登録 | |
377 | 708 registSessionManager(forwarder, command); |
355 | 709 } else { |
710 if (forwarder.sid==-1) { | |
711 // direct link の場合は、識別のために、EIDに直上の | |
712 // smid を入れておく。 | |
713 command.setEID(smList.sessionManagerID()); | |
714 } | |
715 smList.sendToMaster(command); | |
353 | 716 } |
717 } | |
718 break; | |
719 | |
355 | 720 case SMCMD_SM_JOIN_ACK: |
721 send_sm_join_ack(command.eid, command.sid, command); | |
353 | 722 break; |
723 | |
724 case SMCMD_UPDATE: | |
359
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
725 if (!isMaster()) { |
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
726 command.setString(mergeUpdate(command)); |
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
727 // 上に知らせる |
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
728 smList.sendToMaster(command); |
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
729 break; |
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
730 } |
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
731 // fall thru |
fa041bae35f1
all code written for distributed session except gather.
kono
parents:
358
diff
changeset
|
732 command.setCMD(REP.SMCMD_UPDATE_ACK); |
353 | 733 case SMCMD_UPDATE_ACK: |
358 | 734 command.setString(mergeUpdate(command)); |
735 // 下に知らせる | |
355 | 736 smList.sendToSlaves(command); |
358 | 737 updateGUI(); |
353 | 738 break; |
739 default: | |
740 return false; | |
741 } | |
742 return true; | |
743 } | |
744 | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
745 private void registSessionManager(REPNode forwarder, REPCommand command) { |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
746 REPNode sm; |
377 | 747 int psid = command.eid; |
748 if (forwarder.sid!=-1) { | |
749 // すでに channelはSessionManager Idを持っていて、 | |
750 // direct link ではないので、 | |
751 // channel を持たないForwarderとして登録する | |
752 sm = new Forwarder(this); | |
753 } else { | |
754 sm = forwarder; | |
755 } | |
756 int sid = smList.addNewSessionManager(sm,command); | |
757 routingTable.add(forwarder,sid); | |
758 | |
759 REPCommand sendCommand = makeREPCommandWithSessionList(REP.SMCMD_SM_JOIN_ACK); | |
760 // command.eid==smList.sesionManagerID() の場合は、 | |
761 // 待っている自分の下のsessionManagerにsidをassignする必要がある。 | |
762 sendCommand.setSID(sid); // new Session manager ID | |
763 // 複数のSM_JOIN_ACKを識別するには、最初にSM_JOINを受け付けた | |
764 // Session manager IDを使う。 | |
765 sendCommand.setEID(psid); | |
766 send_sm_join_ack(psid, sid, sendCommand); | |
767 } | |
768 | |
769 | |
770 void send_sm_join_ack(int psid, int sid,REPCommand sendCommand) { | |
771 if (psid==smList.sessionManagerID()) { | |
772 // 直下のsessionManagerにIDを割り振る必要がある。 | |
773 smList.assignSessionManagerIDtoWaitingSM(sid); | |
774 // ここで smList に一つだけ追加されるので | |
775 // 待っている最初のsm一つにだけ、sm_join_ackが新たに送られる。 | |
776 } | |
777 smList.sendToSlaves(sendCommand); | |
778 } | |
779 | |
372 | 780 /* |
781 * 指定されたeditorがlocalにあるかどうかを調べる。なければ、他に送る。戻って何回も探すことが | |
782 * あり得るので、よろしくない。 | |
783 */ | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
784 private void searchSelectedEditor(REPCommand command, REPNode editor) { |
372 | 785 for(;editor.isDirect();editor = editor.getNextForwarder()) { |
786 if (editor.getEID()==command.eid) { | |
787 // select したeditor を見つけた | |
788 command.cmd=REP.SMCMD_JOIN_ACK; | |
789 editor.send(command); | |
790 return; | |
791 } | |
792 } | |
793 // ここにはありませんでした。 | |
794 editor.send(command); | |
795 } | |
796 | |
355 | 797 |
363 | 798 /** |
799 * UPDATE/UPDATE_ACKにより送られてきたSessionの情報を追加する | |
800 * @param command | |
801 * @return | |
802 * @throws IOException | |
803 */ | |
358 | 804 private String mergeUpdate(REPCommand command) throws IOException { |
805 SessionList receivedSessionList; | |
806 try { | |
807 receivedSessionList = decoder.decode(command.string); | |
808 } catch (SAXException e) { | |
809 throw new IOException(); | |
810 } | |
363 | 811 // 受け取った情報と自分の情報を混ぜる。 |
812 sessionList.merge(receivedSessionList); | |
358 | 813 //XMLを生成。送信コマンドにセット。 |
814 return encoder.sessionListToXML(sessionList); | |
815 | |
816 } | |
817 | |
818 /* | |
819 * id has SessionManager ID part | |
820 */ | |
821 private int makeID(int newid) { | |
822 return newid+smList.sessionManagerID()*MAXID; | |
823 } | |
824 | |
825 private int getSMID(int id) { | |
826 return id/MAXID; | |
827 } | |
828 | |
829 | |
361 | 830 /** |
831 * Register Editor to our editorList. No connection is made. | |
832 * @param forwarder Editor to be add | |
833 * @param command | |
834 */ | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
835 public void registEditor(REPNode forwarder,REPCommand command) { |
358 | 836 // make ack for PUT/JOIN. Do not send this to the editor, |
837 // before select. After select, ack is sent to the editor. | |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
838 REPNode editor; |
367 | 839 if (getSMID(command.eid)==smList.sessionManagerID()) { |
840 if (forwarder.isDirect()) { | |
841 editor = (Editor)forwarder; | |
842 } else | |
843 return; | |
358 | 844 } else { |
845 editor = new Editor(this, command.cmd==REP.SMCMD_PUT_ACK, command.eid); | |
846 } | |
847 editor.setName(command.string); | |
848 editor.setSID(command.sid); | |
849 if (!editorList.hasEid(command.eid)) { | |
850 editorList.add(editor); | |
851 } | |
367 | 852 if (command.cmd==REP.SMCMD_PUT_ACK) { |
853 Session session = new Session(command.sid, command.string, editor); | |
854 sessionList.put(command.sid, session); | |
855 } | |
358 | 856 // we don't join ack to the direct linked editor. We |
857 // have to wait select command | |
858 } | |
859 | |
860 | |
355 | 861 private REPCommand makeREPCommandWithSessionList(REP cmd) { |
862 //SessionListからXMLを生成。 | |
863 //joinしてきたSessionManagerに対してACKを送信。 | |
864 REPCommand sendCommand = new REPCommand(); | |
865 sendCommand.setCMD(cmd); | |
358 | 866 sendCommand.setString(encoder.sessionListToXML(sessionList)); |
355 | 867 return sendCommand; |
868 } | |
869 | |
870 | |
871 public boolean isMaster() { | |
872 return smList.isMaster(); | |
873 } | |
874 | |
875 | |
876 public void setSessionManagerID(int sid) { | |
877 smList.setSessionManagerID(sid); | |
878 } | |
879 | |
358 | 880 |
881 public Session getSession(int sid) { | |
882 return sessionList.get(sid); | |
883 } | |
884 | |
365
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
885 public void execAfterConnect(SessionManagerEvent sessionManagerEvent) { |
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
886 execAfterConnect = sessionManagerEvent; |
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
887 } |
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
888 |
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
889 public void afterConnect() { |
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
890 if (execAfterConnect!=null) execAfterConnect.exec(this); |
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
891 execAfterConnect = null; |
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
892 } |
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
893 |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
894 public void setParent(REPNode fw) { |
365
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
895 smList.setParent(fw); |
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
896 } |
367 | 897 |
898 public String toString() { | |
899 int myId = 0; | |
900 if (smList!=null) myId = smList.sessionManagerID(); | |
901 return "rep.SessionManager-"+myId+"@"+myHost+":"+receive_port; | |
902 } | |
365
c432755c3555
distributed session debug continue... SELECT/SELECT_ACK loop
kono
parents:
364
diff
changeset
|
903 |
382
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
904 public void addWaitingSessionManager(REPNode fw, REPCommand command) { |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
905 smList.addWaitingSessionManager(fw, command) ; |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
906 } |
4b87f89b3afd
REP Session Manager (Java version)
one@firefly.cr.ie.u-ryukyu.ac.jp
parents:
378
diff
changeset
|
907 |
364 | 908 |
0 | 909 } |