|
1 #!/usr/bin/env python |
|
2 # -*- coding: utf-8 -*- |
|
3 # |
|
4 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD |
|
5 # |
|
6 #See COPYING file for copyrights details. |
|
7 # |
|
8 #This library is free software; you can redistribute it and/or |
|
9 #modify it under the terms of the GNU General Public |
|
10 #License as published by the Free Software Foundation; either |
|
11 #version 2.1 of the License, or (at your option) any later version. |
|
12 # |
|
13 #This library is distributed in the hope that it will be useful, |
|
14 #but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
15 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
16 #General Public License for more details. |
|
17 # |
|
18 #You should have received a copy of the GNU General Public |
|
19 #License along with this library; if not, write to the Free Software |
|
20 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
21 import Pyro.core as pyro |
|
22 from Pyro.errors import PyroError |
|
23 import traceback |
|
24 from time import sleep |
|
25 |
|
26 def PYRO_connector_factory(uri, pluginsroot): |
|
27 """ |
|
28 This returns the connector to Pyro style PLCobject |
|
29 """ |
|
30 pluginsroot.logger.write("Connecting to URI : %s\n"%uri) |
|
31 |
|
32 servicetype, location = uri.split("://") |
|
33 |
|
34 # Try to get the proxy object |
|
35 try : |
|
36 RemotePLCObjectProxy = pyro.getAttrProxyForURI("PYROLOC://"+location+"/PLCObject") |
|
37 except Exception, msg: |
|
38 pluginsroot.logger.write_error("Wrong URI, please check it !\n") |
|
39 pluginsroot.logger.write_error(traceback.format_exc()) |
|
40 return None |
|
41 |
|
42 def PyroCatcher(func, default=None): |
|
43 """ |
|
44 A function that catch a pyro exceptions, write error to logger |
|
45 and return defaul value when it happen |
|
46 """ |
|
47 def cather_func(*args,**kwargs): |
|
48 try: |
|
49 return func(*args,**kwargs) |
|
50 except PyroError,e: |
|
51 #pluginsroot.logger.write_error(traceback.format_exc()) |
|
52 pluginsroot.logger.write_error(str(e)) |
|
53 pluginsroot._Disconnect() |
|
54 return default |
|
55 return cather_func |
|
56 |
|
57 # Check connection is effective. |
|
58 # lambda is for getattr of GetPLCstatus to happen inside catcher |
|
59 if PyroCatcher(lambda:RemotePLCObjectProxy.GetPLCstatus())() == None: |
|
60 pluginsroot.logger.write_error("Cannot get PLC status - connection failed.\n") |
|
61 return None |
|
62 |
|
63 class PyroProxyProxy: |
|
64 """ |
|
65 A proxy proxy class to handle Beremiz Pyro interface specific behavior. |
|
66 And to put pyro exception catcher in between caller and pyro proxy |
|
67 """ |
|
68 def GetPyroProxy(self): |
|
69 """ |
|
70 This func returns the real Pyro Proxy. |
|
71 Use this if you musn't keep reference to it. |
|
72 """ |
|
73 return RemotePLCObjectProxy |
|
74 |
|
75 def __getattr__(self, attrName): |
|
76 if not self.__dict__.has_key(attrName): |
|
77 if attrName=="StartPLC": |
|
78 def _StartPLC(): |
|
79 """ |
|
80 pluginsroot._connector.GetPyroProxy() is used |
|
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 |
|
103 return self.__dict__[attrName] |
|
104 return PyroProxyProxy() |
|
105 |
|
106 |