runtime/PyroServer.py
changeset 3800 a5a6ee271e65
parent 3750 f62625418bff
child 3805 5a66d4be2e49
--- a/runtime/PyroServer.py	Wed May 10 17:02:05 2023 +0200
+++ b/runtime/PyroServer.py	Fri May 12 18:09:55 2023 +0200
@@ -14,11 +14,42 @@
 import sys
 import os
 
-import Pyro
-import Pyro.core as pyro
+import Pyro5
+import Pyro5.server
+
 import runtime
 from runtime.ServicePublisher import ServicePublisher
 
+def make_pyro_exposed_stub(method_name):
+    stub = lambda self, *args, **kwargs: \
+        getattr(self.plc_object_instance, method_name)(self, *args, **kwargs)
+    stub.__name__ = method_name
+    Pyro5.server.expose(stub)
+    return stub
+    
+
+class PLCObjectPyroAdapter(type("PLCObjectPyroStubs", (), {
+    name: make_pyro_exposed_stub(name) for name in [
+        "AppendChunkToBlob",
+        "GetLogMessage",
+        "GetPLCID",
+        "GetPLCstatus",
+        "GetTraceVariables",
+        "MatchMD5", 
+        "NewPLC",
+        "PurgeBlobs",
+        "RemoteExec",
+        "RepairPLC",
+        "ResetLogCount",
+        "SeedBlob",
+        "SetTraceVariablesList",
+        "StartPLC",
+        "StopPLC"
+    ]
+})):
+    def __init__(self, plc_object_instance):
+        self.plc_object_instance = plc_object_instance
+    
 
 class PyroServer(object):
     def __init__(self, servicename, ip_addr, port):
@@ -47,33 +78,14 @@
             self.Publish()
 
         while self.continueloop:
-            Pyro.config.PYRO_MULTITHREADED = 0
-            pyro.initServer()
-            self.daemon = pyro.Daemon(host=self.ip_addr, port=self.port)
+            self.daemon = Pyro5.server.Daemon(host=self.ip_addr, port=self.port)
 
-            # pyro never frees memory after connection close if no timeout set
-            # taking too small timeout value may cause
-            # unwanted diconnection when IDE is kept busy for long periods
-            self.daemon.setTimeout(60)
-
-            pyro_obj = Pyro.core.ObjBase()
-            pyro_obj.delegateTo(runtime.GetPLCObjectSingleton())
-
-            self.daemon.connect(pyro_obj, "PLCObject")
+            self.daemon.register(PLCObjectPyroAdapter(runtime.GetPLCObjectSingleton()), "PLCObject")
 
             when_ready()
 
-            # "pipe to self" trick to to accelerate runtime shutdown 
-            # instead of waiting for arbitrary pyro timeout.
-            others = []
-            if not sys.platform.startswith('win'):
-                self.piper, self.pipew = os.pipe()
-                others.append(self.piper)
+            self.daemon.requestLoop()
 
-            self.daemon.requestLoop(others=others, callback=lambda x: None)
-            self.piper, self.pipew = None, None
-            if hasattr(self, 'sock'):
-                self.daemon.sock.close()
         self.Unpublish()
 
     def Restart(self):
@@ -81,8 +93,7 @@
 
     def Quit(self):
         self.continueloop = False
-        self.daemon.shutdown(True)
-        self.daemon.closedown()
+        self.daemon.shutdown()
         if not sys.platform.startswith('win'):
             if self.pipew is not None:
                 os.write(self.pipew, "goodbye")