OEBInteractiveServers.Mod 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. MODULE OEBInteractiveServers;
  2. (**
  3. AUTHOR Timothée Martiel, 05/2016
  4. PURPOSE Interactive deployment server
  5. *)
  6. IMPORT
  7. Modules, KernelLog, Strings, FoxBasic,
  8. OEBInterfaces, OEBServers;
  9. CONST
  10. Ok * = 0;
  11. SessionNotFound * = 1;
  12. InvalidSessionState * = 2;
  13. CommandError * = 3;
  14. Name = "Interactive";
  15. Type = "Interactive Server";
  16. TYPE
  17. Server * = OBJECT (OEBServers.Server)
  18. VAR
  19. event: LONGINT;
  20. interface: OEBInterfaces.Interface;
  21. session: OEBInterfaces.Session;
  22. sessions: FoxBasic.List;
  23. (*out, error: Streams.Writer;*)
  24. handle: BOOLEAN;
  25. PROCEDURE & Init * (*(out, error: Streams.Writer)*);
  26. VAR
  27. name: ARRAY 128 OF CHAR;
  28. BEGIN
  29. name := Name;
  30. Strings.AppendInt(name, nextId);
  31. INC(nextId);
  32. InitServer(name, Type);
  33. (*SELF.out := out;
  34. SELF.error := error*)
  35. NEW(sessions, 0)
  36. END Init;
  37. PROCEDURE Handle * (event: LONGINT; interface: OEBInterfaces.Interface; session: OEBInterfaces.Session);
  38. BEGIN {EXCLUSIVE}
  39. TRACE('RECEIVED', event, interface.name, session.name);
  40. AWAIT(~handle);
  41. SELF.event := event;
  42. SELF.interface := interface;
  43. SELF.session := session;
  44. handle := TRUE
  45. END Handle;
  46. PROCEDURE DoHandle;
  47. VAR
  48. reply: ARRAY 128 OF CHAR;
  49. info: SessionInfo;
  50. i: LONGINT;
  51. BEGIN
  52. TRACE(event, session.name, interface.name);
  53. IF event = OEBInterfaces.EventEnter THEN
  54. IF sessions.Length() > 0 THEN
  55. EnterTrace;
  56. KernelLog.String("Closing previous session");
  57. ExitTrace;
  58. sessions.Get(0)(SessionInfo).session.Close;
  59. sessions.Clear();
  60. END;
  61. IF ~interface.Command(session, "nop", reply) THEN
  62. EnterTrace;
  63. KernelLog.String("Could not get handle on session ");
  64. KernelLog.String(interface.name);
  65. KernelLog.String("/");
  66. KernelLog.String(session.name);
  67. KernelLog.String(": ");
  68. KernelLog.String(reply);
  69. ExitTrace;
  70. session.Close;
  71. BEGIN {EXCLUSIVE}
  72. handle := FALSE
  73. END;
  74. RETURN
  75. END;
  76. NEW(info);
  77. info.session := session;
  78. info.interface := interface;
  79. sessions.Add(info);
  80. EnterTrace;
  81. KernelLog.String("New session: ");
  82. KernelLog.String(interface.name);
  83. KernelLog.String("/");
  84. KernelLog.String(session.name);
  85. KernelLog.String(" as ");
  86. KernelLog.Int(sessions.IndexOf(info), 0);
  87. ExitTrace
  88. ELSE
  89. FOR i := 0 TO sessions.Length() - 1 DO
  90. info := sessions.Get(i)(SessionInfo);
  91. IF info.session = session THEN
  92. sessions.Remove(info);
  93. KernelLog.Enter;
  94. KernelLog.String("Removed session: ");
  95. KernelLog.Int(i, 0);
  96. KernelLog.String("(");
  97. KernelLog.String(interface.name);
  98. KernelLog.String("/");
  99. KernelLog.String(session.name);
  100. KernelLog.String(")");
  101. KernelLog.Exit
  102. END
  103. END
  104. END;
  105. BEGIN {EXCLUSIVE}
  106. handle := FALSE
  107. END
  108. END DoHandle;
  109. PROCEDURE GetSession * (id: LONGINT): OEBInterfaces.Session;
  110. VAR
  111. info: SessionInfo;
  112. BEGIN {EXCLUSIVE}
  113. info := sessions.Get(id)(SessionInfo);
  114. IF info = NIL THEN RETURN NIL END;
  115. RETURN info.session
  116. END GetSession;
  117. PROCEDURE GetInterface * (id: LONGINT): OEBInterfaces.Interface;
  118. VAR
  119. info: SessionInfo;
  120. BEGIN {EXCLUSIVE}
  121. info := sessions.Get(id)(SessionInfo);
  122. IF info = NIL THEN RETURN NIL END;
  123. RETURN info.interface
  124. END GetInterface;
  125. PROCEDURE ExecuteCommand * (id: LONGINT; CONST cmd: ARRAY OF CHAR; VAR msg: ARRAY OF CHAR): LONGINT;
  126. VAR
  127. interface: OEBInterfaces.Interface;
  128. session: OEBInterfaces.Session;
  129. BEGIN
  130. session := GetSession(id);
  131. TRACE(session, session.State());
  132. IF session = NIL THEN RETURN SessionNotFound END;
  133. IF session.State() IN {OEBInterfaces.SessionClosed, OEBInterfaces.SessionError} THEN
  134. RETURN InvalidSessionState
  135. END;
  136. interface := GetInterface(id);
  137. TRACE(interface);
  138. ASSERT(interface # NIL);
  139. IF interface.Command(session, cmd, msg) THEN
  140. TRACE(msg);
  141. RETURN Ok
  142. ELSE
  143. TRACE(msg);
  144. RETURN CommandError
  145. END
  146. END ExecuteCommand;
  147. BEGIN {ACTIVE}
  148. LOOP
  149. BEGIN {EXCLUSIVE} AWAIT(handle) END;
  150. DoHandle
  151. END
  152. END Server;
  153. SessionInfo = POINTER TO RECORD
  154. session: OEBInterfaces.Session;
  155. interface: OEBInterfaces.Interface;
  156. END;
  157. Factory = OBJECT (OEBServers.Factory)
  158. PROCEDURE NewServer (CONST param: ARRAY OF CHAR): OEBServers.Server;
  159. VAR
  160. server: Server;
  161. BEGIN
  162. NEW(server);
  163. RETURN server
  164. END NewServer;
  165. END Factory;
  166. VAR
  167. factory: Factory;
  168. nextId: LONGINT;
  169. PROCEDURE Cleanup;
  170. BEGIN
  171. OEBServers.Unregister(factory)
  172. END Cleanup;
  173. BEGIN
  174. NEW(factory);
  175. OEBServers.Register("Interactive", factory);
  176. Modules.InstallTermHandler(Cleanup)
  177. END OEBInteractiveServers.