मैं सॉकेटसेवर का उपयोग करने वाले SimpleXMLRPCServers की एक श्रृंखला का उपयोग करते समय एक httplib.CannotSendRequest अपवाद प्राप्त कर रहा हूं। थ्रेडिंगमिक्सिन।पायथन: httplib.CannotSendRequest जब थ्रेडेड नेक्सिंग किया जाता है SimpleXMLRPCServers
मैं जो एक SimpleXMLRPCServer पर एक समारोह कॉल करने के लिए xmlrpclib का उपयोग करता है एक ग्राहक स्क्रिप्ट है:
मैं 'श्रृंखला' से क्या मतलब पीछा कर रहा है। वह सर्वर, बदले में, एक और SimpleXMLRPCServer को कॉल करता है। मुझे एहसास है कि यह कितना गड़बड़ है, लेकिन अच्छे कारण हैं कि इस वास्तुकला का चयन किया गया है, और मुझे कोई कारण नहीं दिख रहा है कि यह संभव नहीं होना चाहिए।
(testclient)client_script ---calls-->
(middleserver)SimpleXMLRPCServer ---calls--->
(finalserver)SimpleXMLRPCServer --- does something
- अगर मैं SocketServer.ThreadingMixin का उपयोग नहीं करते तो यह समस्या तब उत्पन्न नहीं करता है (लेकिन मैं अनुरोध की जरूरत मल्टी-थ्रेडेड होने के लिए तो यह मदद नहीं करता है।)
- यदि मैं केवल है सेवाओं का एक स्तर (यानी केवल ग्राहक स्क्रिप्ट कॉलिंग अंतिम सर्वर सीधे) ऐसा नहीं होता है।
मैं इस मुद्दे को नीचे दिए गए सरल परीक्षण कोड में पुन: उत्पन्न करने में सक्षम हूं। वहाँ तीन के टुकड़े कर रहे हैं:
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()
पुन: पेश करने के लिए निम्न चरणों का उपयोग किया जाना चाहिए:
- रन अजगर finalserver.py
- रन अजगर middleserver.py
- रन अजगर testclient.py
- जबकि (3) अभी भी चल रहा है,
काफी अजगर testclient.py का एक और उदाहरण चलाने अक्सर (लगभग हर बार) आपको चरण 4 चलाने की कोशिश करते समय पहली बार त्रुटि मिल जाएगी। दिलचस्प बात यह है कि यदि आप तुरंत चरण (4) चलाने की कोशिश करते हैं तो त्रुटि नहीं होगी।
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'>:">
इंटरनेट कहना है कि इस अपवाद getresponse कॉल हस्तक्षेप के बिना httplib.HTTPConnection.request को कई कॉल के कारण हो सकता प्रकट होता है। हालांकि, इंटरनेट SimpleXMLRPCServer के संदर्भ में इस पर चर्चा नहीं करता है। Httplib.CannotSendRequest मुद्दे को हल करने की दिशा में कोई भी पॉइंटर्स की सराहना की जाएगी।
============================================== ===============================================12=64=उत्तर:
ठीक है, मैं थोड़ा बेवकूफ हूँ। मुझे लगता है कि मैं उस समय बहुत लंबे समय तक कोड पर घूर रहा था, जिसने मुझे चेहरे पर घूरने वाले स्पष्ट समाधान को याद किया (वास्तव में, क्योंकि वास्तव में वास्तविक प्रश्न वास्तव में वास्तविक प्रश्न में है।)
असल में, कैनोटसेन्डआरक्वेट होता है जब एक httplib.HTTPConnection एक हस्तक्षेप 'अनुरोध' ऑपरेशन द्वारा बाधित है।प्रत्येक httplib.HTTPConnection.request को .getresponse() कॉल के साथ जोड़ा जाना चाहिए। यदि वह युग्मन किसी अन्य अनुरोध ऑपरेशन द्वारा बाधित है, तो दूसरा अनुरोध CannotSendRequest त्रुटि उत्पन्न करेगा। इसलिए:
connection = httplib.HTTPConnection(...)
connection.request(...)
connection.request(...)
विफल हो जाएगा क्योंकि आपके पास किसी भी प्रतिक्रिया के पहले एक ही कनेक्शन पर दो अनुरोध हैं।
मेरे सवाल का कि वापस लिंक करना:
- केवल जगह तीन कार्यक्रमों जहां इस तरह के कनेक्शन किए जा रहे हैं में serverproxy कॉल में हैं।
- समस्या केवल थ्रेडिंग के दौरान होती है, इसलिए यह दौड़ की स्थिति की संभावना है।
- केवल जगह एक serverproxy कॉल साझा किया जाता है, समाधान तो middleserver.py
में है प्रत्येक थ्रेड बनाने यह खुद serverproxy है के लिए स्पष्ट रूप से है। 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()
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()
के बाद से अपनी ही xmlrpclib.serverproxy होने प्रत्येक सूत्र में इस संस्करण परिणाम, वहाँ एक ही उदाहरण serverproxy की लागू का कोई खतरा नहीं HTTPConnection.request अधिक है उत्तराधिकार में एक बार से अधिक। कार्यक्रम इरादे के रूप में काम करते हैं।
परेशानियों के लिए खेद है।