Можно ли кешировать клиент Python suds?

В настоящее время я использую python suds для файла wsdl и соответствующих ему 50+ файлов xsd. Следующий звонок Client занимает около 90 секунд:

from suds.client import Client
url = 'http://localhost:7080/webservices/WebServiceTestBean?wsdl'
client = Client(url)

После запуска последней строки выше я получаю Client пример. Создание этого клиента занимает много времени. Работает ли кэширование с объектами Python или оно ограничено примитивами, такими как строки и целые числа?

Вот что я хочу сделать в коде, синтаксис неправильный, но он должен передать то, что я хочу:

from suds.client import Client


if 'current_client' in cache:
    client = cache.get('current_client')
else:
    url = 'http://localhost:7080/webservices/WebServiceTestBean?wsdl'
    client = Client(url)
    cache.put('current_client', client)

4 ответа

По умолчанию suds кэширует файлы WSDL и XSD на один день, поэтому для каждого экземпляра объекта Client не требуется отдельный URL-запрос.

90 секунд - это действительно очень много времени, это время, потраченное на ожидание ответа wsdl, или оно потрачено на разбор wsdl? Если его анализ занимает так много времени, встроенное кэширование мало чем поможет.

Я делал что-то подобное раньше, но вместо шаблона синглтона я просто использовал глобальный словарь уровня модуля. Это шаблон синглтона без всех class шум.

Что-то вроде этого:

from suds.client import Client

_clients = {}

def get_client(name):
    if name not in _clients:
        _clients[name] = Client(url_for_name)
    return _clients[name]

Вы пробовали это?

Что касается Python, проблем не должно быть. Большой проблемой любого кэша является поддержание согласованности, но то, как вы это сделаете, будет зависеть от приложения, а не от Python.

suds >= 0.3.5 r473 обеспечивает некоторое кэширование URL. По умолчанию http get(s), такие как получение WSDL и импорт XSD, кэшируются.

Если я хорошо понимаю вашу проблему, я думаю, что вы не хотите каждый раз создавать новый Client() и помещать его в кеш, чтобы вы могли получить его; но я думаю, что вы усложняете задачу, и я предлагаю использовать шаблон синглтона, это позволит вам создать только один экземпляр клиента, и каждый раз, когда вы захотите создать новый экземпляр, он просто вернет старый созданный экземпляр.

Вот пример, который может помочь вам понять, что я предлагаю.

class MyClient(Client):

    __instance__ = None

    def __new__(cls, *args, **kws):
        if not cls.__instance__:
            cls.__instance__ = super(Client, cls).__new__(cls, *args, **kws)
        return cls.__instance__

NB: я хотел использовать паттерн Борг, который похож на синглтон, но красивее, но я не смог понять, как не называть Super.init (который занимает много времени) и в то же время разделяет одно и то же состояние, если у кого-то есть лучшее представление о том, как поставить его с помощью шаблона Borg, это будет здорово, но я не думаю, что шаблон borg может быть полезным в этом случае

Надеюсь, что это может помочь

Другие вопросы по тегам