Python, suds - การจัดการกับแคชและการตอบกลับ WSDL ที่เน่าเสีย

ในช่วงสองสามวันที่ผ่านมา ฉันได้ต่อสู้กับเซิร์ฟเวอร์ SOAP โง่ๆ

ในบันทึกข้อผิดพลาดของฉัน ฉันได้รับข้อยกเว้น / บันทึกการติดตามที่มีลักษณะดังนี้: "ข้อยกเว้น: (วิดเจ็ต, ไม่มี, ), ต้องเป็น qref" -- (วลีสำคัญคือ "ต้องเป็น qref").

ก่อนอื่น ฉันพบว่าเรามีแคชเน่าๆ ดังนั้นฉันจึงปิดการใช้งานแคช แต่ปัญหายังคงดำเนินต่อไป

ประการที่สอง ฉันคิดว่ามันเป็นความผิดของเซิร์ฟเวอร์จริงๆ ที่ไม่ได้ให้ WSDL ที่เหมาะสมแก่ฉันแบบสุ่ม โดยเฉพาะอย่างยิ่งเมื่อใช้อินสแตนซ์ของผู้ปฏิบัติงานหลายราย ข่าวด่วน - ผู้ติดต่อผู้ให้บริการเซิร์ฟเวอร์ของฉันยืนยันว่ามีข้อผิดพลาด "เซิร์ฟเวอร์ยุ่งเกินไป" ในบันทึกของเขา “วันเดอร์บาร์!” เห็นได้ชัดว่าเซิร์ฟเวอร์เปลี่ยนเส้นทางไปยังหน้า HTTP 200 เมื่อควรจะมี HTTP 503

ฉันสงสัยว่าจะทำตัวสง่างามมากขึ้นในการจัดการกับพฤติกรรมแย่ๆ เหล่านี้ได้อย่างไร และฉันก็พบวิธีแก้ปัญหาทั่วไปที่มีประโยชน์และค่อนข้างทั่วถึง โพสต์ที่นี่เพื่อใช้อ้างอิงในอนาคต


person starlocke    schedule 08.05.2014    source แหล่งที่มา


คำตอบ (1)


บางสิ่งเช่นนี้:

from suds.client import Client
from suds.transport.https import HttpAuthenticated
from suds.xsd.doctor import ImportDoctor, Import
import os
import shutil
import time
from tempfile import gettempdir as tmp

class MyTransport(HttpAuthenticated):
    def __init__(self,*args,**kwargs):
        HttpAuthenticated.__init__(self,*args,**kwargs)
        self.last_headers = None
    def send(self,request):
        result = HttpAuthenticated.send(self,request)
        self.last_headers = result.headers
        return result

class TenaciousConnector():
    def init_client(self, wsdl_url):
        retries = 3
        services = None
        # Cached mode
        (client, services) = self._init_client(wsdl_url)
        while not services and retries > 0:
            nap_time = 6 - retries
            retries = retries - 1
            time.sleep(nap_time)
            # clear potentially rotten cache right before retrying
            shutil.rmtree(os.path.join(tmp(), 'suds'), True)
            (client, services) = self._init_client(wsdl_url)
        if not services:
            # No-cache mode
            retries = 3
            (client, services) = self._init_client(wsdl_url, False)
            while not services and retries > 0:
                nap_time = 6 - retries
                retries = retries - 1
                time.sleep(nap_time)
                (client, services) = self._init_client(wsdl_url, False)
        if not services:
            raise Exception("Failed at loading WSDL from {0}".format(wsdl_url))
        return client

    def _init_client(self, wsdl_url, cache=True):
        i_doc = ImportDoctor(Import('http://schemas.xmlsoap.org/soap/encoding/'))
        tx = MyTransport()
        if cache:
            client = Client(wsdl_url, doctor=i_doc, transport=tx)
        else:
            client = Client(wsdl_url, doctor=i_doc, transport=tx, cache=None)
        services = client.wsdl.services
        return (client, services)

ใช้ในลักษณะนี้:

connector = TenaciousConnector()
client = connector.init_client("http://example.com/webservice/wsdl")
client.factory.create('Widget')
person starlocke    schedule 08.05.2014