Beremiz_service.py
changeset 1994 1fdc32be71b8
parent 1988 19ca02e8074f
child 1997 d9e8fb47340f
equal deleted inserted replaced
1993:cbf0a9ffc782 1994:1fdc32be71b8
    28 from __future__ import print_function
    28 from __future__ import print_function
    29 import os
    29 import os
    30 import sys
    30 import sys
    31 import getopt
    31 import getopt
    32 import threading
    32 import threading
    33 from threading import Thread, currentThread, Semaphore
    33 from threading import Thread, currentThread, Semaphore, Lock
    34 import traceback
    34 import traceback
    35 import __builtin__
    35 import __builtin__
       
    36 import Pyro
    36 import Pyro.core as pyro
    37 import Pyro.core as pyro
    37 
    38 
    38 from runtime import PLCObject, ServicePublisher, MainWorker
    39 from runtime import PLCObject, ServicePublisher, MainWorker
    39 import util.paths as paths
    40 import util.paths as paths
    40 
    41 
   397     except Exception:
   398     except Exception:
   398         res = (None, sys.exc_info())
   399         res = (None, sys.exc_info())
   399     return res
   400     return res
   400 
   401 
   401 
   402 
       
   403 
   402 class Server(object):
   404 class Server(object):
   403     def __init__(self, servicename, ip_addr, port,
   405     def __init__(self, servicename, ip_addr, port,
   404                  workdir, argv,
   406                  workdir, argv,
   405                  statuschange=None, evaluator=default_evaluator,
   407                  statuschange=None, evaluator=default_evaluator,
   406                  pyruntimevars=None):
   408                  pyruntimevars=None):
   434             print(_("Publishing service on local network"))
   436             print(_("Publishing service on local network"))
   435 
   437 
   436         sys.stdout.flush()
   438         sys.stdout.flush()
   437 
   439 
   438 
   440 
   439     def PyroLoop(self):
   441     def PyroLoop(self, when_ready):
   440         while self.continueloop:
   442         while self.continueloop:
       
   443             Pyro.config.PYRO_MULTITHREADED = 0
   441             pyro.initServer()
   444             pyro.initServer()
   442             self.daemon = pyro.Daemon(host=self.ip_addr, port=self.port)
   445             self.daemon = pyro.Daemon(host=self.ip_addr, port=self.port)
   443 
   446 
   444             # pyro never frees memory after connection close if no timeout set
   447             # pyro never frees memory after connection close if no timeout set
   445             # taking too small timeout value may cause
   448             # taking too small timeout value may cause
   450 
   453 
   451             if self._to_be_published():
   454             if self._to_be_published():
   452                 self.servicepublisher = ServicePublisher.ServicePublisher()
   455                 self.servicepublisher = ServicePublisher.ServicePublisher()
   453                 self.servicepublisher.RegisterService(self.servicename, self.ip_addr, self.port)
   456                 self.servicepublisher.RegisterService(self.servicename, self.ip_addr, self.port)
   454 
   457 
       
   458             when_ready()
   455             self.daemon.requestLoop()
   459             self.daemon.requestLoop()
   456             self.daemon.sock.close()
   460             self.daemon.sock.close()
   457 
   461 
   458     def Restart(self):
   462     def Restart(self):
   459         self._stop()
   463         self._stop()
   629             else:
   633             else:
   630                 raise Exception(_("WAMP config is missing."))
   634                 raise Exception(_("WAMP config is missing."))
   631         except Exception:
   635         except Exception:
   632             LogMessageAndException(_("WAMP client startup failed. "))
   636             LogMessageAndException(_("WAMP client startup failed. "))
   633 
   637 
   634 pyro_thread = Thread(target=pyroserver.PyroLoop)
   638 pyro_thread_started = Lock()
       
   639 pyro_thread_started.acquire()
       
   640 pyro_thread = Thread(target=pyroserver.PyroLoop,
       
   641                      kwargs=dict(when_ready=pyro_thread_started.release))
   635 pyro_thread.start()
   642 pyro_thread.start()
   636 
   643 
       
   644 # Wait for pyro thread to be effective
       
   645 pyro_thread_started.acquire()
       
   646 
   637 pyroserver.PrintServerInfo()
   647 pyroserver.PrintServerInfo()
   638 
   648 
   639 if havetwisted or havewx:
   649 if havetwisted or havewx:
       
   650     ui_thread_started = Lock()
       
   651     ui_thread_started.acquire()
   640     if havetwisted:
   652     if havetwisted:
   641         # reactor._installSignalHandlersAgain()
   653         # reactor._installSignalHandlersAgain()
   642         def ui_thread_target():
   654         def ui_thread_target():
   643             # FIXME: had to disable SignaHandlers install because 
   655             # FIXME: had to disable SignaHandlers install because 
   644             # signal not working in non-main thread
   656             # signal not working in non-main thread
   647         ui_thread_target = app.MainLoop
   659         ui_thread_target = app.MainLoop
   648 
   660 
   649     ui_thread = Thread(target = ui_thread_target)
   661     ui_thread = Thread(target = ui_thread_target)
   650     ui_thread.start()
   662     ui_thread.start()
   651 
   663 
       
   664     # This order ui loop to unblock main thread when ready.
       
   665     if havetwisted:
       
   666         reactor.callLater(0,ui_thread_started.release)
       
   667     else :
       
   668         wx.CallAfter(ui_thread_started.release)
       
   669 
       
   670     # Wait for ui thread to be effective
       
   671     ui_thread_started.acquire()
       
   672     print("UI thread started successfully.")
       
   673 
   652 try:
   674 try:
   653     MainWorker.runloop(pyroserver.AutoLoad)
   675     MainWorker.runloop(pyroserver.AutoLoad)
   654 except KeyboardInterrupt:
   676 except KeyboardInterrupt:
   655     pass
   677     pass
   656 
   678