首页 > 编程语言 > 详细

Tornado/Python 学习笔记(二)

时间:2014-07-16 18:14:13      阅读:451      评论:0      收藏:0      [点我收藏+]

部分ssrpc.py代码分析 -- 服务端:

 1 #!/usr/bin/python3
 2 
 3 from xmlrpc.client import Fault, dumps, loads
 4 import sys
 5 from socketserver import ForkingMixIn
 6 from xmlrpc.server import SimpleXMLRPCServer
 7 
 8 class VerboseFaultXMLRPCServer(SimpleXMLRPCServer):
 9     def _marshaled_dispatch(self, data, dispatch_method = None, path = None):
10         """Dispatches an XML-RPC method from marshalled (XML) data.
11 
12         XML-RPC methods are dispatched from the marshalled (XML) data
13         using the _dispatch method and the result is returned as
14         marshalled data. For backwards compatibility, a dispatch
15         function can be provided as an argument (see comment in
16         SimpleXMLRPCRequestHandler.do_POST) but overriding the
17         existing method through subclassing is the preferred means
18         of changing method dispatch behavior.
19         """
20 
21         try:
22             params, method = loads(data)
23 
24             # generate response
25             if dispatch_method is not None:
26                 response = dispatch_method(method, params)
27             else:
28                 response = self._dispatch(method, params)
29             # wrap response in a singleton tuple
30             response = (response,)
31             response = dumps(response, methodresponse=1,
32                              allow_none=self.allow_none, encoding=self.encoding)
33         except Fault as fault:
34             response = dumps(fault, allow_none=self.allow_none,
35                              encoding=self.encoding)
36         except:
37             # report exception back to server
38             exc_type, exc_value, exc_tb = sys.exc_info()
39             while exc_tb.tb_next is not None:
40                 exc_tb = exc_tb.tb_next  # find last frame of the traceback
41             lineno = exc_tb.tb_lineno
42             code = exc_tb.tb_frame.f_code
43             filename = code.co_filename
44             name = code.co_name
45             response = dumps(
46                 Fault(1, "%s:%s FILENAME: %s LINE: %s NAME: %s" % (
47                     exc_type, exc_value, filename, lineno, name)),
48                 encoding=self.encoding, allow_none=self.allow_none,
49                 )
50 
51         return response.encode(self.encoding)
52 
53 # One process per request
54 class ForkingXMLRPCServer(ForkingMixIn, VerboseFaultXMLRPCServer):
55     max_children = 500    # default is 40
56 
57 server = ForkingXMLRPCServer(("", 8889), allow_none=True)
58 
59 # Register functions here
60 
61 from ssapi.disk.sas import sasdiskinfo
62 from ssapi.disk.ledctl import ledctl_set
63 from ssapi.zfs.zpoollist import zpoollist
64 from ssapi.zfs.zpoolstatus import zpoolstatus
65 from ssapi.zfs.zpoolcreate import zpoolcreate
66 
67 funcs = [
68     sasdiskinfo,
69     ledctl_set,
70     zpoollist,
71     zpoolstatus,
72     zpoolcreate,
73     ]
74 
75 for i in funcs:
76     server.register_function(i)
77 
78 # Start service
79 server.serve_forever()

正如上篇文章所述,SimpleXMLRPCServer是一个单线程的服务器,所以这里支持多进程的方式如下:

1.定义VerboseFaultXMLRPCServer类,继承于SimpleXMLRPCServer

2.定义一个新类:ForkingXMLRPCServer(ForkingMixIn, VerboseFaultXMLRPCServer),其中ForkingMixIn是从socketserver中导入

3.调用新类创建server实体,server = ForkingXMLRPCServer(("", 8889), allow_none=True),则支持多进程

 

/usr/lib/python3.2/xmlrpc/server.py 中SimpleXMLRPCServer源代码:

 

 1 class SimpleXMLRPCServer(socketserver.TCPServer,
 2                          SimpleXMLRPCDispatcher):
 3     """Simple XML-RPC server.
 4 
 5     Simple XML-RPC server that allows functions and a single instance
 6     to be installed to handle requests. The default implementation
 7     attempts to dispatch XML-RPC calls to the functions or instance
 8     installed in the server. Override the _dispatch method inherited
 9     from SimpleXMLRPCDispatcher to change this behavior.
10     """
11 
12     allow_reuse_address = True
13 
14     # Warning: this is for debugging purposes only! Never set this to True in
15     # production code, as will be sending out sensitive information (exception
16     # and stack trace details) when exceptions are raised inside
17     # SimpleXMLRPCRequestHandler.do_POST
18     _send_traceback_header = False
19 
20     def __init__(self, addr, requestHandler=SimpleXMLRPCRequestHandler,
21                  logRequests=True, allow_none=False, encoding=None, bind_and_activate=True):
22         self.logRequests = logRequests
23 
24         SimpleXMLRPCDispatcher.__init__(self, allow_none, encoding)
25         socketserver.TCPServer.__init__(self, addr, requestHandler, bind_and_activate)
26 
27         # [Bug #1222790] If possible, set close-on-exec flag; if a
28         # method spawns a subprocess, the subprocess shouldn‘t have
29         # the listening socket open.
30         if fcntl is not None and hasattr(fcntl, FD_CLOEXEC):
31             flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFD)
32             flags |= fcntl.FD_CLOEXEC
33             fcntl.fcntl(self.fileno(), fcntl.F_SETFD, flags)

 

 

Tornado/Python 学习笔记(二),布布扣,bubuko.com

Tornado/Python 学习笔记(二)

原文:http://www.cnblogs.com/fendou-999/p/3845467.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!