SocketServer.ThreadingMixin kullanan bir SimpleXMLRPCServers zinciri kullanırken aralıklı olarak bir httplib.CannotSendRequest özel durumu alıyorum.python: iş parçacığı oluştururken httplib.CannotSendRequest SimpleXMLRPCServers
Bir SimpleXMLRPCServer bir işlevi çağırmak için xmlrpclib kullanan bir istemci komut dosyası vardır: Ben 'zincir' kastım
şudur. Bu sunucu, sırayla başka bir SimpleXMLRPCServer çağırır. Kulağa ne kadar sarsıldığının farkındayım, ama bu mimarinin seçilmesinin iyi nedenleri var ve bunun mümkün olmaması için bir neden göremiyorum. Ben SocketServer.ThreadingMixin kullanmazsanız
(testclient)client_script ---calls-->
(middleserver)SimpleXMLRPCServer ---calls--->
(finalserver)SimpleXMLRPCServer --- does something
- sonra bu sorun oluşmaz (ama yani bu yardımcı olmuyor çok kanallı olması isteklerini gerekir.) Ben sadece varsa
- Tek bir hizmet seviyesi (yani, doğrudan sunucuya doğrudan son çağrı yapan müşteri komut dosyası) bu gerçekleşmez.
Sorunu aşağıdaki basit test kodunda yeniden üretebiliyorum. Üç parçacıkları vardır:
finalserver:
import SocketServer
import time
from SimpleXMLRPCServer import SimpleXMLRPCServer
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler
class AsyncXMLRPCServer(SocketServer.ThreadingMixIn,SimpleXMLRPCServer): pass
# Create server
server = AsyncXMLRPCServer(('', 9999), SimpleXMLRPCRequestHandler)
server.register_introspection_functions()
def waste_time():
time.sleep(10)
return True
server.register_function(waste_time, 'waste_time')
server.serve_forever()
middleserver:
import SocketServer
from SimpleXMLRPCServer import SimpleXMLRPCServer
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler
import xmlrpclib
class AsyncXMLRPCServer(SocketServer.ThreadingMixIn,SimpleXMLRPCServer): pass
# Create server
server = AsyncXMLRPCServer(('', 8888), SimpleXMLRPCRequestHandler)
server.register_introspection_functions()
s = xmlrpclib.ServerProxy('http://localhost:9999')
def call_waste():
s.waste_time()
return True
server.register_function(call_waste, 'call_waste')
server.serve_forever()
Testclient:
import xmlrpclib
s = xmlrpclib.ServerProxy('http://localhost:8888')
print s.call_waste()
yeniden oluşturmak için aşağıdaki adımlar kullanılmalıdır:
- Çalıştır piton finalserver.py
- Çalıştır piton middleserver.py
- Çalıştır piton testclient.py (3) hala, piton testclient.py başka bir örneğini
Oldukça çalıştırmak çalışırken
Traceback (most recent call last):
File "testclient.py", line 6, in <module>
print s.call_waste()
File "/usr/lib64/python2.7/xmlrpclib.py", line 1224, in __call__
return self.__send(self.__name, args)
File "/usr/lib64/python2.7/xmlrpclib.py", line 1578, in __request
verbose=self.__verbose
File "/usr/lib64/python2.7/xmlrpclib.py", line 1264, in request
return self.single_request(host, handler, request_body, verbose)
File "/usr/lib64/python2.7/xmlrpclib.py", line 1297, in single_request
return self.parse_response(response)
File "/usr/lib64/python2.7/xmlrpclib.py", line 1473, in parse_response
return u.close()
File "/usr/lib64/python2.7/xmlrpclib.py", line 793, in close
raise Fault(**self._stack[0])
xmlrpclib.Fault: <Fault 1: "<class 'httplib.CannotSendRequest'>:">
internet bu istisna GetResponse çağrıları müdahale etmeden httplib.HTTPConnection.request için birden aramaların neden olabilir söylemek görünmektedir. Ancak, internet bunu SimpleXMLRPCServer bağlamında tartışmıyor. Httplib.CannotSendRequest sorununu çözme yönünde herhangi bir işaretçi takdir edilecektir.
================================= YANIT:
Tamam, biraz aptalım. Ben çok uzun bir süre için kod dik dik baktığımı düşünüyorum bir süre içinde yüzüne dik dik bakıyordu açık çözüm özledim (gerçekten tam anlamıyla, gerçek soru yanıttır.)
Temel olarak, CannotSendRequest oluşur Bir httplib.HTTPConnection araya giren bir 'istek' işlemi tarafından kesintiye uğradığında.Her bir httplib.HTTPConnection.request bir .getresponse() çağrısı ile eşleştirilmelidir. Bu eşleştirme başka bir istek işlemiyle kesintiye uğrarsa, ikinci istek CannotSendRequest hatasını üretecektir. Bu nedenle, herhangi bir yanıt verilmeden önce aynı bağlantıda iki isteğiniz olduğundan, başarısız olacaktır. Böyle bağlantıları yapılıyor üç programlarında
- tek yer serverproxy çağrılarında şunlardır: Sorumun Sözünü geri Bağlama
.
- Sorun yalnızca iş parçacığı sırasında ortaya çıkıyor, bu nedenle büyük olasılıkla bir yarış durumu. Bir serverproxy çağrı paylaşılır
- tek yer, çözelti daha sonra middleserver.py
olduğu her iş parçacığı kendi serverproxy var oluşturmasını sağlamak için belli ki. middleserver sabit versiyonu altında ve çalışır: kendi xmlrpclib.serverproxy sahip her dizisindeki bu sürüm sonuçları yana
import SocketServer
from SimpleXMLRPCServer import SimpleXMLRPCServer
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler
import xmlrpclib
class AsyncXMLRPCServer(SocketServer.ThreadingMixIn,SimpleXMLRPCServer): pass
# Create server
server = AsyncXMLRPCServer(('', 8888), SimpleXMLRPCRequestHandler)
server.register_introspection_functions()
def call_waste():
# Each call to this function creates its own serverproxy.
# If this function is called by concurrent threads, each thread
# will safely have its own serverproxy.
s = xmlrpclib.ServerProxy('http://localhost:9999')
s.waste_time()
return True
server.register_function(call_waste, 'call_waste')
server.serve_forever()
, serverproxy ait çağırma aynı örneğinin riski HTTPConnection.request fazlası var art arda bir kez. Programlar amaçlandığı gibi çalışır.
Rahatsız ettiğim için özür dilerim.