runtime/PyroServer.py
author Edouard Tisserant <edouard.tisserant@gmail.com>
Wed, 17 May 2023 23:59:45 +0200
changeset 3806 b57a38ce3f34
parent 3805 5a66d4be2e49
child 3808 3e219f00151a
permissions -rw-r--r--
IDE: Fix py_ext build with python3.10
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     1
#!/usr/bin/env python
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     2
# -*- coding: utf-8 -*-
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     3
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     4
# This file is part of Beremiz runtime.
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     5
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     6
# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     7
# Copyright (C) 2017: Andrey Skvortsov
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     8
# Copyright (C) 2018: Edouard TISSERANT
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
     9
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    10
# See COPYING file for copyrights details.
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    11
3750
f62625418bff automated conversion using 2to3-3.9 tool
GP Orcullo <kinsamanka@gmail.com>
parents: 3311
diff changeset
    12
f62625418bff automated conversion using 2to3-3.9 tool
GP Orcullo <kinsamanka@gmail.com>
parents: 3311
diff changeset
    13
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    14
import sys
2603
1ffdc62784cf Add some "pipe to self" trick in Pyro server to accelerate runtime shutdown instead of waiting for arbitrary pyro timeout.
Edouard Tisserant
parents: 2492
diff changeset
    15
import os
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    16
3800
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    17
import Pyro5
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    18
import Pyro5.server
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    19
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    20
import runtime
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    21
from runtime.ServicePublisher import ServicePublisher
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    22
3800
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    23
def make_pyro_exposed_stub(method_name):
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    24
    stub = lambda self, *args, **kwargs: \
3805
5a66d4be2e49 Pyro5: fix runtime typo + IDE exception handling
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3800
diff changeset
    25
        getattr(self.plc_object_instance, method_name)(*args, **kwargs)
3800
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    26
    stub.__name__ = method_name
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    27
    Pyro5.server.expose(stub)
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    28
    return stub
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    29
    
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    30
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    31
class PLCObjectPyroAdapter(type("PLCObjectPyroStubs", (), {
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    32
    name: make_pyro_exposed_stub(name) for name in [
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    33
        "AppendChunkToBlob",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    34
        "GetLogMessage",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    35
        "GetPLCID",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    36
        "GetPLCstatus",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    37
        "GetTraceVariables",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    38
        "MatchMD5", 
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    39
        "NewPLC",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    40
        "PurgeBlobs",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    41
        "RemoteExec",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    42
        "RepairPLC",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    43
        "ResetLogCount",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    44
        "SeedBlob",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    45
        "SetTraceVariablesList",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    46
        "StartPLC",
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    47
        "StopPLC"
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    48
    ]
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    49
})):
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    50
    def __init__(self, plc_object_instance):
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    51
        self.plc_object_instance = plc_object_instance
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    52
    
2309
d8fb90a2e11f Please pylint and pep8
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2270
diff changeset
    53
2476
1881d0ff5ae2 PyroServer: fixed naming of class, and reorganized methods in order to ease subclassing, in case of customization of service publication on the local network (i.e. zeroconf)
Edouard Tisserant
parents: 2315
diff changeset
    54
class PyroServer(object):
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    55
    def __init__(self, servicename, ip_addr, port):
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    56
        self.continueloop = True
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    57
        self.daemon = None
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    58
        self.servicename = servicename
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    59
        self.ip_addr = ip_addr
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    60
        self.port = port
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    61
        self.servicepublisher = None
2603
1ffdc62784cf Add some "pipe to self" trick in Pyro server to accelerate runtime shutdown instead of waiting for arbitrary pyro timeout.
Edouard Tisserant
parents: 2492
diff changeset
    62
        self.piper, self.pipew = None, None
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    63
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    64
    def _to_be_published(self):
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    65
        return self.servicename is not None and \
2311
bef2b4b87370 Beremiz_service now binds both pyro and nevow ports to interface given with '-i' argument.
Edouard Tisserant
parents: 2270
diff changeset
    66
               self.ip_addr not in ["", "localhost", "127.0.0.1"]
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    67
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    68
    def PrintServerInfo(self):
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    69
        print(_("Pyro port :"), self.port)
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    70
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    71
        if self._to_be_published():
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    72
            print(_("Publishing service on local network"))
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    73
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    74
        sys.stdout.flush()
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    75
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    76
    def PyroLoop(self, when_ready):
2492
7dd551ac2fa0 check_sources.sh makes me become even less productive
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2476
diff changeset
    77
        if self._to_be_published():
7dd551ac2fa0 check_sources.sh makes me become even less productive
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2476
diff changeset
    78
            self.Publish()
7dd551ac2fa0 check_sources.sh makes me become even less productive
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2476
diff changeset
    79
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    80
        while self.continueloop:
3800
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    81
            self.daemon = Pyro5.server.Daemon(host=self.ip_addr, port=self.port)
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    82
3800
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    83
            self.daemon.register(PLCObjectPyroAdapter(runtime.GetPLCObjectSingleton()), "PLCObject")
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    84
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    85
            when_ready()
3308
358ccd42e052 Runtime: avoids using "pipe to self" bailout unblocking trick on windows, since select() only takes sockets.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2625
diff changeset
    86
3800
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    87
            self.daemon.requestLoop()
3308
358ccd42e052 Runtime: avoids using "pipe to self" bailout unblocking trick on windows, since select() only takes sockets.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2625
diff changeset
    88
2476
1881d0ff5ae2 PyroServer: fixed naming of class, and reorganized methods in order to ease subclassing, in case of customization of service publication on the local network (i.e. zeroconf)
Edouard Tisserant
parents: 2315
diff changeset
    89
        self.Unpublish()
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    90
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    91
    def Restart(self):
2476
1881d0ff5ae2 PyroServer: fixed naming of class, and reorganized methods in order to ease subclassing, in case of customization of service publication on the local network (i.e. zeroconf)
Edouard Tisserant
parents: 2315
diff changeset
    92
        self.daemon.shutdown(True)
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    93
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    94
    def Quit(self):
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
    95
        self.continueloop = False
3800
a5a6ee271e65 WIP python3 support for runtime
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3750
diff changeset
    96
        self.daemon.shutdown()
3308
358ccd42e052 Runtime: avoids using "pipe to self" bailout unblocking trick on windows, since select() only takes sockets.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2625
diff changeset
    97
        if not sys.platform.startswith('win'):
358ccd42e052 Runtime: avoids using "pipe to self" bailout unblocking trick on windows, since select() only takes sockets.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2625
diff changeset
    98
            if self.pipew is not None:
358ccd42e052 Runtime: avoids using "pipe to self" bailout unblocking trick on windows, since select() only takes sockets.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 2625
diff changeset
    99
                os.write(self.pipew, "goodbye")
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   100
2476
1881d0ff5ae2 PyroServer: fixed naming of class, and reorganized methods in order to ease subclassing, in case of customization of service publication on the local network (i.e. zeroconf)
Edouard Tisserant
parents: 2315
diff changeset
   101
    def Publish(self):
1881d0ff5ae2 PyroServer: fixed naming of class, and reorganized methods in order to ease subclassing, in case of customization of service publication on the local network (i.e. zeroconf)
Edouard Tisserant
parents: 2315
diff changeset
   102
        self.servicepublisher = ServicePublisher("PYRO")
1881d0ff5ae2 PyroServer: fixed naming of class, and reorganized methods in order to ease subclassing, in case of customization of service publication on the local network (i.e. zeroconf)
Edouard Tisserant
parents: 2315
diff changeset
   103
        self.servicepublisher.RegisterService(self.servicename,
1881d0ff5ae2 PyroServer: fixed naming of class, and reorganized methods in order to ease subclassing, in case of customization of service publication on the local network (i.e. zeroconf)
Edouard Tisserant
parents: 2315
diff changeset
   104
                                              self.ip_addr, self.port)
1881d0ff5ae2 PyroServer: fixed naming of class, and reorganized methods in order to ease subclassing, in case of customization of service publication on the local network (i.e. zeroconf)
Edouard Tisserant
parents: 2315
diff changeset
   105
1881d0ff5ae2 PyroServer: fixed naming of class, and reorganized methods in order to ease subclassing, in case of customization of service publication on the local network (i.e. zeroconf)
Edouard Tisserant
parents: 2315
diff changeset
   106
    def Unpublish(self):
2270
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   107
        if self.servicepublisher is not None:
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   108
            self.servicepublisher.UnRegisterService()
d9175daf6522 Refactoring. Separated PLC Object, PYRO Server and MainWorker :
Edouard Tisserant
parents:
diff changeset
   109
            self.servicepublisher = None