~openerp-groupes/openobject-server/6.0-fix-setup-windows

« back to all changes in this revision

Viewing changes to bin/netsvc.py

  • Committer: pinky
  • Date: 2006-12-07 13:41:40 UTC
  • Revision ID: pinky-3f10ee12cea3c4c75cef44ab04ad33ef47432907
New trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
 
 
3
import time
 
4
import threading
 
5
 
 
6
import SimpleXMLRPCServer,signal,sys,xmlrpclib
 
7
import SocketServer
 
8
import socket
 
9
import logging
 
10
 
 
11
try:
 
12
        from ssl import *
 
13
        HAS_SSL = True
 
14
except ImportError:
 
15
        HAS_SSL = False
 
16
 
 
17
_service={}
 
18
_group={}
 
19
_res_id=1
 
20
_res={}
 
21
 
 
22
class ServiceEndPointCall(object):
 
23
        def __init__(self,id,method):
 
24
                self._id=id
 
25
                self._meth=method
 
26
        def __call__(self,*args):
 
27
                _res[self._id]=self._meth(*args)
 
28
                return self._id
 
29
 
 
30
class ServiceEndPoint(object):
 
31
        def __init__(self, name, id):
 
32
                self._id = id
 
33
                self._meth={}
 
34
                print _service
 
35
                s=_service[name]
 
36
                for m in s._method:
 
37
                        self._meth[m]=s._method[m]
 
38
        def __getattr__(self, name):
 
39
                return ServiceEndPointCall(self._id, self._meth[name])
 
40
 
 
41
class Service(object):
 
42
        _serviceEndPointID = 0
 
43
        def __init__(self, name, audience=''):
 
44
                _service[name]=self
 
45
                self.__name=name
 
46
                self._method={}
 
47
                self.exportedMethods=None
 
48
                self._response_process=None
 
49
                self._response_process_id=None
 
50
                self._response=None
 
51
                
 
52
        def joinGroup(self,name):
 
53
                if not name in _group:
 
54
                        _group[name]={}
 
55
                _group[name][self.__name]=self
 
56
                
 
57
        def exportMethod(self, m):
 
58
                if callable(m):
 
59
                        self._method[m.__name__]=m
 
60
 
 
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)
 
66
 
 
67
        def conversationId(self):
 
68
                return 1
 
69
 
 
70
        def processResponse(self,s,id):
 
71
                self._response_process, self._response_process_id = s, id
 
72
 
 
73
        def processFailure(self,s,id):
 
74
                pass
 
75
 
 
76
        def resumeResponse(self,s):
 
77
                pass
 
78
 
 
79
        def cancelResponse(self,s):
 
80
                pass
 
81
 
 
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)
 
88
 
 
89
        def abortResponse(self,error, description, origin, details):
 
90
                import tools
 
91
                if not tools.config['debug_mode']:
 
92
                        raise Exception("%s -- %s\n\n%s"%(origin,description,details))
 
93
                else:
 
94
                        raise
 
95
 
 
96
        def currentFailure(self,s):
 
97
                pass
 
98
 
 
99
class LocalService(Service):
 
100
        def __init__(self, name):
 
101
                self.__name=name
 
102
                s=_service[name]
 
103
                self._service=s
 
104
                for m in s._method:
 
105
                        setattr(self,m,s._method[m])
 
106
 
 
107
class ServiceUnavailable(Exception):
 
108
        pass
 
109
 
 
110
LOG_DEBUG='debug'
 
111
LOG_INFO='info'
 
112
LOG_WARNING='warn'
 
113
LOG_ERROR='error'
 
114
LOG_CRITICAL='critical'
 
115
 
 
116
def init_logger():
 
117
        from tools import config
 
118
        import os
 
119
 
 
120
        if config['logfile']:
 
121
                logf = config['logfile']
 
122
                # test if the directories exist, else create them
 
123
                try:
 
124
                        if not os.path.exists(os.path.dirname(logf)):
 
125
                                os.makedirs(os.path.dirname(logf))
 
126
                        try:
 
127
                                fd = open(logf, 'a')
 
128
                                print 'OK'
 
129
                                handler = logging.StreamHandler(fd)
 
130
                        except IOError:
 
131
                                print 'H1'
 
132
                                sys.stderr.write("ERROR: couldn't open the logfile\n")
 
133
                                handler = logging.StreamHandler(sys.stdout)
 
134
                except OSError:
 
135
                        print 'H2'
 
136
                        sys.stderr.write("ERROR: couldn't create the logfile directory\n")
 
137
                        handler = logging.StreamHandler(sys.stdout)
 
138
        else:
 
139
                handler = logging.StreamHandler(sys.stdout)
 
140
 
 
141
        # create a format for log messages and dates
 
142
        formatter = logging.Formatter('%(asctime)s %(levelname)s:%(name)s:%(message)s', '%a, %d %b %Y %H:%M:%S')
 
143
 
 
144
        # tell the handler to use this format
 
145
        handler.setFormatter(formatter)
 
146
 
 
147
        # add the handler to the root logger
 
148
        logging.getLogger().addHandler(handler)
 
149
        logging.getLogger().setLevel(logging.INFO)
 
150
 
 
151
 
 
152
class Logger(object):
 
153
        def notifyChannel(self,name,level,msg):
 
154
                log = logging.getLogger(name)
 
155
                getattr(log,level)(msg)
 
156
 
 
157
class Agent(object):
 
158
        _timers = []
 
159
        _logger = Logger()
 
160
 
 
161
        def setAlarm(self, fn, dt, args=[], kwargs={}):
 
162
                wait = dt - time.time()
 
163
                if wait > 0:
 
164
                        self._logger.notifyChannel(
 
165
                                        'timers', LOG_DEBUG,
 
166
                                        "Job scheduled in %s seconds for %s.%s" % (wait,
 
167
                                                                                                                           fn.im_class.__name__,
 
168
                                                                                                fn.func_name))
 
169
                        timer = threading.Timer(wait, fn, args, kwargs)
 
170
                        timer.start()
 
171
                        self._timers.append(timer)
 
172
                for timer in self._timers[:]:
 
173
                        if not timer.isAlive():
 
174
                                self._timers.remove(timer)
 
175
 
 
176
        def quit(cls):
 
177
                for timer in cls._timers:
 
178
                        timer.cancel()
 
179
        quit=classmethod(quit)
 
180
 
 
181
class RpcGateway(object):
 
182
        def __init__(self, name):
 
183
                self.name=name
 
184
 
 
185
class Dispatcher(object):
 
186
        def __init__(self):
 
187
                pass
 
188
        def monitor(self,signal):
 
189
                pass
 
190
        def run(self):
 
191
                pass
 
192
 
 
193
class xmlrpc(object):
 
194
        class RpcGateway(object):
 
195
                def __init__(self, name):
 
196
                        self.name=name
 
197
 
 
198
class GenericXMLRPCRequestHandler:
 
199
        def _dispatch(self, method, params):
 
200
                import traceback
 
201
                try:
 
202
                        n=self.path.split("/")[-1]
 
203
#                       print "TERP-CALLING:",n,method,params
 
204
                        s=LocalService(n)
 
205
                        m=getattr(s,method)
 
206
                        s._service._response=None
 
207
                        r=m(*params)
 
208
                        res=s._service._response
 
209
                        if res!=None:
 
210
#                               print "RESPONSE FOUND"
 
211
                                r=res
 
212
#                       print "TERP-RETURN :",r
 
213
                        return r
 
214
                except Exception,e:
 
215
                        print "Exception in call:"
 
216
                        print '-'*60
 
217
                        traceback.print_exc(file=sys.stdout)
 
218
                        print '-'*60
 
219
                        s=str(e)
 
220
                        import tools
 
221
                        if tools.config['debug_mode']:
 
222
                                import pdb
 
223
                                tb = sys.exc_info()[2]
 
224
                                pdb.post_mortem(tb)
 
225
                        raise xmlrpclib.Fault(1,s)
 
226
 
 
227
class SimpleXMLRPCRequestHandler(GenericXMLRPCRequestHandler, SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
 
228
        pass
 
229
 
 
230
if HAS_SSL:
 
231
        class SecureXMLRPCRequestHandler(GenericXMLRPCRequestHandler, SecureXMLRPCServer.SecureXMLRPCRequestHandler):
 
232
                pass
 
233
else:
 
234
        pass
 
235
 
 
236
class SimpleThreadedXMLRPCServer(SocketServer.ThreadingMixIn, SimpleXMLRPCServer.SimpleXMLRPCServer):
 
237
        def server_bind(self):
 
238
                self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 
239
                SimpleXMLRPCServer.SimpleXMLRPCServer.server_bind(self)
 
240
 
 
241
if HAS_SSL:
 
242
        class SecureThreadedXMLRPCServer(SocketServer.ThreadingMixIn, SecureXMLRPCServer.SecureXMLRPCServer):
 
243
                def server_bind(self):
 
244
                        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 
245
                        SecureXMLRPCServer.SecureXMLRPCServer.server_bind(self)
 
246
else:
 
247
        pass
 
248
 
 
249
class HttpDaemon(object):
 
250
        def __init__(self, interface,port, secure=False):
 
251
                self.__port=port
 
252
                self.__interface=interface
 
253
                if secure and HAS_SSL:
 
254
                        self.server = SecureThreadedXMLRPCServer((interface, port), SecureXMLRPCRequestHandler,0)
 
255
                else:
 
256
                        self.server = SimpleThreadedXMLRPCServer((interface, port), SimpleXMLRPCRequestHandler,0)
 
257
 
 
258
        def attach(self,path,gw):
 
259
                pass
 
260
 
 
261
        def handler(self,signum, frame):
 
262
                self.server.socket.close()
 
263
                self.server.socket.close()
 
264
                Agent.quit()
 
265
#               if tools.config['pidfile']:
 
266
#                       os.unlink(tools.config['pidfile'])
 
267
                del self.server
 
268
                sys.exit(0)
 
269
 
 
270
        def start(self):
 
271
#               if tools.config['pidfile']:
 
272
#                       fd=open(tools.config['pidfile'], 'w')
 
273
#                       pidtext="%d" % (os.getpid())
 
274
#                       fd.write(pidtext)
 
275
#                       fd.close()
 
276
                signal.signal(signal.SIGINT, self.handler)
 
277
                signal.signal(signal.SIGTERM, self.handler)
 
278
                self.server.register_introspection_functions()
 
279
 
 
280
                self.server.serve_forever()
 
281
 
 
282
                # If the server need to be run recursively
 
283
                #
 
284
                #signal.signal(signal.SIGALRM, self.my_handler)
 
285
                #signal.alarm(6)
 
286
                #while True:
 
287
                #       self.server.handle_request()
 
288
                #signal.alarm(0)          # Disable the alarm
 
289
 
 
290
# vim:noexpandtab:
 
291
 
 
292