connectors/PYRO/__init__.py
changeset 231 f1db3ce8f40a
parent 218 71fddab24be9
child 235 a66e150f2888
equal deleted inserted replaced
230:38feaca5f06b 231:f1db3ce8f40a
    20 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    20 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    21 import Pyro.core as pyro
    21 import Pyro.core as pyro
    22 from Pyro.errors import PyroError
    22 from Pyro.errors import PyroError
    23 import traceback
    23 import traceback
    24 from time import sleep
    24 from time import sleep
       
    25 import copy
    25 
    26 
    26 def PYRO_connector_factory(uri, pluginsroot):
    27 def PYRO_connector_factory(uri, pluginsroot):
    27     """
    28     """
    28     This returns the connector to Pyro style PLCobject
    29     This returns the connector to Pyro style PLCobject
    29     """
    30     """
    57     # Check connection is effective. 
    58     # Check connection is effective. 
    58     # lambda is for getattr of GetPLCstatus to happen inside catcher
    59     # lambda is for getattr of GetPLCstatus to happen inside catcher
    59     if PyroCatcher(lambda:RemotePLCObjectProxy.GetPLCstatus())() == None:
    60     if PyroCatcher(lambda:RemotePLCObjectProxy.GetPLCstatus())() == None:
    60         pluginsroot.logger.write_error("Cannot get PLC status - connection failed.\n")
    61         pluginsroot.logger.write_error("Cannot get PLC status - connection failed.\n")
    61         return None
    62         return None
       
    63 
       
    64     # for safe use in from debug thread, must create a copy
       
    65     RemotePLCObjectProxyCopy = copy.copy(RemotePLCObjectProxy)
    62         
    66         
    63     class PyroProxyProxy:
    67     class PyroProxyProxy:
    64         """
    68         """
    65         A proxy proxy class to handle Beremiz Pyro interface specific behavior.
    69         A proxy proxy class to handle Beremiz Pyro interface specific behavior.
    66         And to put pyro exception catcher in between caller and pyro proxy
    70         And to put pyro exception catcher in between caller and pyro proxy
    69             """
    73             """
    70             This func returns the real Pyro Proxy.
    74             This func returns the real Pyro Proxy.
    71             Use this if you musn't keep reference to it.
    75             Use this if you musn't keep reference to it.
    72             """
    76             """
    73             return RemotePLCObjectProxy
    77             return RemotePLCObjectProxy
       
    78 
       
    79         def _PyroStartPLC(self):
       
    80             """
       
    81             pluginsroot._connector.GetPyroProxy() is used 
       
    82             rather than RemotePLCObjectProxy because
       
    83             object is recreated meanwhile, 
       
    84             so we must not keep ref to it here
       
    85             """
       
    86             if pluginsroot._connector.GetPyroProxy().GetPLCstatus() == "Dirty":
       
    87                 """
       
    88                 Some bad libs with static symbols may polute PLC
       
    89                 ask runtime to suicide and come back again
       
    90                 """
       
    91                 pluginsroot.logger.write("Force runtime reload\n")
       
    92                 pluginsroot._connector.GetPyroProxy().ForceReload()
       
    93                 pluginsroot._Disconnect()
       
    94                 # let remote PLC time to resurect.(freeze app)
       
    95                 sleep(0.5)
       
    96                 pluginsroot._Connect()
       
    97             return pluginsroot._connector.GetPyroProxy().StartPLC()
       
    98         StartPLC = PyroCatcher(_PyroStartPLC, False)
       
    99 
       
   100 
       
   101         def _PyroGetTraceVariables(self):
       
   102             """
       
   103             for safe use in from debug thread, must use the copy
       
   104             """
       
   105             return RemotePLCObjectProxyCopy.GetTraceVariables()
       
   106         GetTraceVariables = PyroCatcher(_PyroGetTraceVariables)
       
   107 
    74         
   108         
    75         def __getattr__(self, attrName):
   109         def __getattr__(self, attrName):
    76             if not self.__dict__.has_key(attrName):
   110             member = self.__dict__.get(attrName, None)
    77                 if attrName=="StartPLC":
   111             if member is None:
    78                     def _StartPLC():
   112                 def my_local_func(*args,**kwargs):
    79                         """
   113                     return RemotePLCObjectProxy.__getattr__(attrName)(*args,**kwargs)
    80                         pluginsroot._connector.GetPyroProxy() is used 
   114                 member = PyroCatcher(my_local_func, None)
    81                         rather than RemotePLCObjectProxy because
       
    82                         object is recreated meanwhile, 
       
    83                         so we must not keep ref to it here
       
    84                         """
       
    85                         if pluginsroot._connector.GetPyroProxy().GetPLCstatus() == "Dirty":
       
    86                             """
       
    87                             Some bad libs with static symbols may polute PLC
       
    88                             ask runtime to suicide and come back again
       
    89                             """
       
    90                             pluginsroot.logger.write("Force runtime reload\n")
       
    91                             pluginsroot._connector.GetPyroProxy().ForceReload()
       
    92                             pluginsroot._Disconnect()
       
    93                             # let remote PLC time to resurect.(freeze app)
       
    94                             sleep(0.5)
       
    95                             pluginsroot._Connect()
       
    96                         return pluginsroot._connector.GetPyroProxy().StartPLC()
       
    97                     member = PyroCatcher(_StartPLC, False)
       
    98                 else:
       
    99                     def my_local_func(*args,**kwargs):
       
   100                         return RemotePLCObjectProxy.__getattr__(attrName)(*args,**kwargs)
       
   101                     member = PyroCatcher(my_local_func, None)
       
   102                 self.__dict__[attrName] = member
   115                 self.__dict__[attrName] = member
   103             return self.__dict__[attrName]
   116             return member
       
   117 
   104     return PyroProxyProxy()
   118     return PyroProxyProxy()
   105     
   119     
   106 
   120