IMP  2.0.1
The Integrative Modeling Platform
ro.py
1 ##
2 ## The Inferential Structure Determination (ISD) software library
3 ##
4 ## Authors: Michael Habeck and Wolfgang Rieping
5 ##
6 ## Copyright (C) Michael Habeck and Wolfgang Rieping
7 ##
8 ## All rights reserved.
9 ##
10 ## NO WARRANTY. This library is provided 'as is' without warranty of any
11 ## kind, expressed or implied, including, but not limited to the implied
12 ## warranties of merchantability and fitness for a particular purpose or
13 ## a warranty of non-infringement.
14 ##
15 ## Distribution of substantively modified versions of this module is
16 ## prohibited without the explicit permission of the copyright holders.
17 ##
18 
19 
20 import sys
21 import time
22 from threading import Event
23 from thread import start_new_thread
24 from numpy.oldnumeric import sum
25 
26 
27 from AbstractGrid import TimeoutError
28 
29 MSG_INIT_DONE = 1
30 MSG_CALL_METHOD = 8
31 MSG_LOOP = 11
32 MSG_INIT = 12
33 MSG_TERMINATE = 14
34 MSG_CLIENT_CRASHED = 2
35 MSG_CALL_METHOD_RESULT = 15
36 MSG_DEL_KEY = 17
37 
38 MSG_INIT_FAILED = 3
39 MSG_SHOW_OUTPUT = 4
40 MSG_STOP = 5
41 MSG_RESULT = 6
42 MSG_QUIT = 7
43 MSG_EXCEPTION = 9
44 MSG_HASATTR = 10
45 MSG_SETATTR = 13
46 
47 MSG_SET_ATTR = 13
48 MSG_GET_ATTR = 10
49 MSG_GET_TIME = 18
50 
51 class MyResult(object):
52 
53  def __init__(self):
54 
55  object.__init__(self)
56 
57  self.__dict__['event'] = Event()
58  self.__dict__['value'] = None
59 
60  def wait(self, timeout = None):
61  self.event.wait(timeout)
62 
63  if timeout is not None:
64 
65  if not self.isSet():
66  raise TimeoutError
67 
68  return self.value
69 
70  def __call__(self):
71  return self.wait()
72 
73  def isSet(self):
74  return self.event.isSet()
75 
76  def set(self):
77  return self.event.set()
78 
79  def clear(self):
80  return self.event.clear()
81 
82 def _wrapper(f, result, *args, **kw):
83 
84  result.value = f(*args, **kw)
85  result.set()
86 
87 def threaded(f, *args, **kw):
88 
89  result = MyResult()
90 
91  start_new_thread(_wrapper, (f, result) + args, kw)
92 
93  return result
94 
95 class RemoteObjectHandler:
96 
97  def __init__(self, kill_on_error = 0, signal_file = '', debug = False):
98 
99  self.debug = debug
100 
101  self.kill_on_error = kill_on_error
102  self.signal_file = signal_file
103 
104  self.bindings = {MSG_QUIT: self.quit,
105  MSG_GET_ATTR: self.getattr,
106  MSG_SET_ATTR: self.setattr,
107  MSG_CALL_METHOD: self.call_method,
108  MSG_TERMINATE: self.terminate,
109  MSG_GET_TIME: self.get_time}
110 
111  self.object = None ## defined in derived classes
112 
113  self.times = []
114  self.t_expire = 30. * 60
115 
116  self.delay = 0.0
117  self.active = 0
118 
119  def send(self, msg, value = None):
120  raise NotImplementedError
121 
122  def recv(self, msg):
123  raise NotImplementedError
124 
125  def setattr(self, name, val):
126 
127  setattr(self.object, name, val)
128  self.send(MSG_SETATTR, None)
129 
130  def getattr(self, name):
131 
132  val = getattr(self.object, name)
133  self.send(MSG_GET_ATTR, val)
134 
135  def call_method(self, key, name, args, kw):
136 
137  #if self.debug: print 'call_method: %s' % name
138 
139  method = getattr(self.object, name)
140 
141  t0 = time.time()
142 
143  result = method(*args, **kw)
144 
145  t = time.time()
146 
147  self.append_time(t, t - t0)
148 
149  t = self.get_time()
150 
151  self.send(MSG_CALL_METHOD_RESULT, (key, result, t))
152 
153  def append_time(self, time_stamp, delta_t):
154 
155  delta_t = abs(delta_t)
156 
157  if delta_t > 100 * 24. * 60. * 60.:
158  return
159 
160  self.times.append({'time_stamp': time_stamp, 'delta': delta_t})
161 
162  self.times = [d for d in self.times if \
163  abs(time_stamp - d['time_stamp']) < self.t_expire]
164 
165  def get_time(self):
166 
167  times = [t['delta'] for t in self.times]
168 
169  if times:
170  t = sum(times) / len(times)
171  else:
172  t = None
173 
174  return t
175 
176  def set_object(self, o):
177  self.object = o
178 
179  def initialize(self):
180  raise NotImplementedError
181 
182  def start(self):
183  raise NotImplementedError
184 
185  def terminate(self):
186  raise NotImplementedError
187 
188  def quit(self):
189 
190  if self.daemon:
191  return
192  else:
193  self.terminate()
194 
195 
196 class RemoteObject(object):
197 
198  def __init__(self, op, handler_tid, manager):
199 
200  object.__init__(self)
201  #print 'calling as %s' % self.__class__.__name__
202 
203  attr_name = '_%s__handler_tid' % self.__class__.__name__
204  #print 'debug2:',attr_name
205  object.__setattr__(self, attr_name, handler_tid)
206  self.__dict__['__handler_tid'] = handler_tid
207 
208  attr_name = '_%s__manager' % self.__class__.__name__
209  object.__setattr__(self, attr_name, manager)
210  self.__dict__['__manager'] = manager
211 
212  self.__dict__['_op'] = op
213  #self.__dict__['key'] = 0
214 
215  def _get_url(self):
216  #return self.__handler_tid
217  return self.__dict__[ '_%s__handler_tid' % self.__class__.__name__]
218 
219  def _call_method(self, name, *args, **kw):
220  raise NotImplementedError
221 
222  def _get_attr(self, value):
223 
224  #print "debug: ",value,self.__handler_tid
225  self.__manager.send(self.__handler_tid, MSG_GET_TIME, value)
226 
227  return self.__manager.recv(self.__handler_tid, MSG_GET_ATTR)
228 
229  def _get_time(self):
230 
231  self.__manager.send(self.__handler_tid, MSG_GET_TIME, None)
232 
233  return self.__manager.recv(self.__handler_tid, MSG_GET_TIME)
234 
235  def __getattr__(self, name):
236 
237  #print 'DEBUG RemoteObject.__getattr__: name = %s (%s)' \
238  # % (name, id(self))
239 
240  if hasattr(self._op, name):
241 
242  val = getattr(self._op, name)
243 
244  if callable(val):
245  return lambda *args, **kw: self._call_method(name, *args, **kw)
246 
247  else:
248  return self._get_attr(name)
249 
250  else:
251  raise AttributeError, 'Attribute %s does not exist' % name
252 
253  def __setattr__(self, name, val):
254 
255  #print 'DEBUG RemoteObject.__setattr__: name = %s, val = %s (%s)' \
256  # % (name, val, id(self))
257 
258  if hasattr(self, name):
259  object.__setattr__(self, name, val)
260  else:
261  self.__manager.send(self.__handler_tid, MSG_SET_ATTR, (name, val))
262 
263 if __name__ == '__main__':
264  ro = RemoteObjectHandler()