6 import SimpleXMLRPCServer,signal,sys,xmlrpclib
23 class ServiceEndPointCall(object):
24 def __init__(self,id,method):
27 def __call__(self,*args):
28 _res[self._id]=self._meth(*args)
31 class ServiceEndPoint(object):
32 def __init__(self, name, id):
37 self._meth[m]=s._method[m]
38 def __getattr__(self, name):
39 return ServiceEndPointCall(self._id, self._meth[name])
41 class Service(object):
42 _serviceEndPointID = 0
43 def __init__(self, name, audience=''):
47 self.exportedMethods=None
48 self._response_process=None
49 self._response_process_id=None
52 def joinGroup(self,name):
53 if not name in _group:
55 _group[name][self.__name]=self
57 def exportMethod(self, m):
59 self._method[m.__name__]=m
61 def serviceEndPoint(self,s):
62 if Service._serviceEndPointID >= 2**16:
63 Service._serviceEndPointID = 0
64 Service._serviceEndPointID += 1
65 return ServiceEndPoint(s, self._serviceEndPointID)
67 def conversationId(self):
70 def processResponse(self,s,id):
71 self._response_process, self._response_process_id = s, id
73 def processFailure(self,s,id):
76 def resumeResponse(self,s):
79 def cancelResponse(self,s):
82 def suspendResponse(self,s):
83 if self._response_process:
84 self._response_process(self._response_process_id,
85 _res[self._response_process_id])
86 self._response_process=None
87 self._response=s(self._response_process_id)
89 def abortResponse(self,error, description, origin, details):
91 if not tools.config['debug_mode']:
92 raise Exception("%s -- %s\n\n%s"%(origin,description,details))
96 def currentFailure(self,s):
99 class LocalService(Service):
100 def __init__(self, name):
105 setattr(self,m,s._method[m])
107 class ServiceUnavailable(Exception):
114 LOG_CRITICAL='critical'
117 from tools import config
120 if config['logfile']:
121 logf = config['logfile']
122 # test if the directories exist, else create them
124 if not os.path.exists(os.path.dirname(logf)):
125 os.makedirs(os.path.dirname(logf))
128 handler = logging.StreamHandler(fd)
130 sys.stderr.write("ERROR: couldn't open the logfile\n")
131 handler = logging.StreamHandler(sys.stdout)
133 sys.stderr.write("ERROR: couldn't create the logfile directory\n")
134 handler = logging.StreamHandler(sys.stdout)
136 handler = logging.StreamHandler(sys.stdout)
138 # create a format for log messages and dates
139 formatter = logging.Formatter('%(asctime)s %(levelname)s:%(name)s:%(message)s', '%a, %d %b %Y %H:%M:%S')
141 # tell the handler to use this format
142 handler.setFormatter(formatter)
144 # add the handler to the root logger
145 logging.getLogger().addHandler(handler)
146 logging.getLogger().setLevel(logging.INFO)
149 class Logger(object):
150 def notifyChannel(self,name,level,msg):
151 log = logging.getLogger(name)
152 getattr(log,level)(msg)
158 def setAlarm(self, fn, dt, args=[], kwargs={}):
159 wait = dt - time.time()
161 self._logger.notifyChannel(
163 "Job scheduled in %s seconds for %s.%s" % (wait,
164 fn.im_class.__name__,
166 timer = threading.Timer(wait, fn, args, kwargs)
168 self._timers.append(timer)
169 for timer in self._timers[:]:
170 if not timer.isAlive():
171 self._timers.remove(timer)
174 for timer in cls._timers:
176 quit=classmethod(quit)
178 class RpcGateway(object):
179 def __init__(self, name):
182 class Dispatcher(object):
185 def monitor(self,signal):
190 class xmlrpc(object):
191 class RpcGateway(object):
192 def __init__(self, name):
195 class GenericXMLRPCRequestHandler:
196 def _dispatch(self, method, params):
199 n=self.path.split("/")[-1]
200 # print "TERP-CALLING:",n,method,params
203 s._service._response=None
205 res=s._service._response
207 # print "RESPONSE FOUND"
209 # print "TERP-RETURN :",r
212 print "Exception in call:"
214 traceback.print_exc(file=sys.stdout)
218 if tools.config['debug_mode']:
220 tb = sys.exc_info()[2]
222 raise xmlrpclib.Fault(1,s)
226 class HttpDaemon(object):
227 def __init__(self, interface,port, secure=False):
229 self.__interface=interface
230 self.server = socket.socket( socket.AF_INET, socket.SOCK_STREAM)
231 self.server.bind((socket.gethostname(), 8085))
232 self.server.listen(5)
234 def attach(self,path,gw):
237 def handler(self,signum, frame):
238 from tools import config
242 if config['pidfile']:
243 os.unlink(config['pidfile'])
248 signal.signal(signal.SIGINT, self.handler)
249 signal.signal(signal.SIGTERM, self.handler)
250 class client_thread(threading.Thread):
252 ts = tiny_socket.mysocket(sock)
255 s=LocalService(msg[0])
257 s._service._response=None
259 res=s._service._response
269 #accept connections from outside
270 (clientsocket, address) = self.server.accept()
271 #now do something with the clientsocket
272 #in this case, we'll pretend this is a threaded server