通过追源码解决:xmlrpc.client设定请求超时时间
一、背景:
我們都知道,RPC本質(zhì)是一個(gè)代理模式,是在HTTP或HTTPS請(qǐng)求上面做的封裝,那么別人封裝好了,拿過(guò)來(lái)用就好了。這樣帶來(lái)了極大的遍歷,但也就導(dǎo)致了另外的問(wèn)題,有的時(shí)候就是不夠靈活。在python項(xiàng)目X山中,有的地方用了xmlrpc.client , 但又缺少超時(shí)機(jī)制。
二、分析
直接上代碼了
import xmlrpc.clienturl = 'http://{}:{}'.format("127.0.0.1", 5678) client = xmlrpc.client.ServerProxy(url) client.f11()
點(diǎn)進(jìn)去看看吧。在短短三行代碼中,我們只能夠發(fā)現(xiàn),只有后兩行,有機(jī)會(huì)傳一個(gè)超時(shí)參數(shù),再一看,倒數(shù)第一行,是自己定義的,那壓力來(lái)到了xmlrpc.client.ServerProxy(url)
這個(gè)構(gòu)造函數(shù),把眼睛看花也看不到timeout字樣,于是搜了搜看到一種解決方案
xmlrpclib客戶端請(qǐng)求超時(shí)-python黑洞網(wǎng)
這老哥說(shuō)到人心坎,全局超時(shí)影響過(guò)于大了,但給的是python2的例子,而且包名和我的報(bào)名也有區(qū)別。
?
此事回頭再看transport參數(shù),
發(fā)現(xiàn)這個(gè)構(gòu)造方法里面也確實(shí)只有這個(gè)參數(shù)能掀起一些波瀾(這個(gè)結(jié)論存在馬后炮成分),并且再構(gòu)造方法里面出現(xiàn)了同名的類:Transport
因此,順著繼承重寫(xiě)方法的路往下走
Transport 類
代碼就不全部粘貼了,搞一部分下來(lái)
## # Standard transport class for XML-RPC over HTTP. # <p> # You can create custom transports by subclassing this method, and # overriding selected methods.class Transport:def make_connection(self, host):#return an existing connection if possible. This allows#HTTP/1.1 keep-alive.if self._connection and host == self._connection[0]:return self._connection[1]# create a HTTP connection object from a host descriptorchost, self._extra_headers, x509 = self.get_host_info(host)self._connection = host, http.client.HTTPConnection(chost)return self._connection[1]class HTTPConnection:def __init__(self, host, port=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,source_address=None, blocksize=8192): ?
關(guān)鍵點(diǎn)1:類前面的備注這里提示我們可以去繼承這個(gè)類
關(guān)鍵點(diǎn)2:方法里面的HTTPConnection也存在timeout參數(shù)
?
繼續(xù)順著這個(gè)思路往下,咱們看看socket._GLOBAL_DEFAULT_TIMEOUT到底是個(gè)啥
這就是個(gè)OBJECT? ????????按照我的預(yù)期,應(yīng)該是個(gè)數(shù)字.......?
給他打印出來(lái)看看
到這里,我覺(jué)得可能不用再追了,我的目標(biāo)是解決問(wèn)題,當(dāng)你設(shè)置為_(kāi)GLOBAL_DEFAULT_TIMEOUT, 那說(shuō)明就是無(wú)限等待的。
三、實(shí)踐
就按照這個(gè)思路,重寫(xiě)了Transport類
客戶端思路如下
import http.client import xmlrpc.clientclass TimeoutTransport(xmlrpc.client.Transport):time_out = 60 # 單位:秒def make_connection(self, host):# return an existing connection if possible. This allows# HTTP/1.1 keep-alive.if self._connection and host == self._connection[0]:return self._connection[1]# create a HTTP connection object from a host descriptorchost, self._extra_headers, x509 = self.get_host_info(host)self._connection = host, http.client.HTTPConnection(chost, timeout=self.time_out)return self._connection[1]def set_timeout(self, timeout):self.time_out = timeouturl = 'http://{}:{}'.format("127.0.0.1", 5678) try:client = xmlrpc.client.ServerProxy(url, transport=TimeoutTransport())client.f11() except Exception as e:print(e) print("--------------------------") try:client2 = xmlrpc.client.ServerProxy(url)client2.f11() except Exception as e:print(e) import sys import time from socketserver import ThreadingMixIn from xmlrpc.server import SimpleXMLRPCServerclass ThreadXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer):name = "xml-server"def f11():print("老子睡了")time.sleep(10000)print("老子醒了")return 11server = ThreadXMLRPCServer(('0.0.0.0', 5678)) server.register_function(f11, "f11") server.serve_forever()四、測(cè)試
server日志客戶端日志:
若是不手動(dòng)停止,怕是永遠(yuǎn)也等不到了呢~
?
?
總結(jié)
以上是生活随笔為你收集整理的通过追源码解决:xmlrpc.client设定请求超时时间的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 追了源码,做了测试,终于实现python
- 下一篇: PostgreSQL(一)Postgre