Можно ли кешировать клиент 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 может быть полезным в этом случае
Надеюсь, что это может помочь