Уведомления

Группа в Telegram: @pythonsu

#1 Апрель 9, 2009 15:23:08

demas
От:
Зарегистрирован: 2008-09-10
Сообщения: 60
Репутация: +  0  -
Профиль   Отправить e-mail  

middle tier

Есть приложение, которое работает с базой данных и имеет несколько клиентов - web-клиент, клиент на PyQt, клиент на PyGtk.

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

То есть, хотется написать некий сервис, который будет принимать запросы от этих клиентов, делать запросы к базе данных и возвращать клиентам результаты запросов, в виде объектов и их коллекций.

Вопрос - как в python между двумя различными python-программами, работающими на разных компах в сети, можно передавать объекты и их коллекции?



Офлайн

#2 Апрель 9, 2009 15:28:59

evgenyl
От:
Зарегистрирован: 2008-07-22
Сообщения: 148
Репутация: +  0  -
Профиль   Отправить e-mail  

middle tier

самое простое что можно придумать asynchat+pickle
ну или вот например http://docs.python.org/library/simplexmlrpcserver.html



Отредактировано (Апрель 9, 2009 15:30:57)

Офлайн

#3 Апрель 9, 2009 16:01:23

demas
От:
Зарегистрирован: 2008-09-10
Сообщения: 60
Репутация: +  0  -
Профиль   Отправить e-mail  

middle tier

А Xml-Rpc позволяет возвращать классы?

Вот мой пример.

Сервер:

from SimpleXMLRPCServer import SimpleXMLRPCServer
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler

# Restrict to a particular path.
class RequestHandler(SimpleXMLRPCRequestHandler):
rpc_paths = ('/RPC2',)

# Create server
server = SimpleXMLRPCServer(("localhost", 8000),
requestHandler=RequestHandler)
server.register_introspection_functions()

class MyClass:
def __init__(self, a):
self.a = a
def say(self):
return a

def return_my_class():
return MyClass(100)

server.register_function(return_my_class, 'my_class')

# Run the server's main loop
server.serve_forever()
Клиент:
import xmlrpclib

s = xmlrpclib.ServerProxy('http://localhost:8000')

o = s.my_class()
print o
o.say()

print s.system.listMethods()
Выводит:
{'a': 100}
Traceback (most recent call last):
File “rpc_client.py”, line 7, in <module>
o.say()
AttributeError: ‘dict’ object has no attribute ‘say’



Офлайн

#4 Апрель 9, 2009 16:06:37

evgenyl
От:
Зарегистрирован: 2008-07-22
Сообщения: 148
Репутация: +  0  -
Профиль   Отправить e-mail  

middle tier

люди читаем что вообще пишем

server.register_function(return_my_class, 'my_class')
register_function`у кормиш класс, разве так можно, а я яй :\ читай доку!



Офлайн

#5 Апрель 9, 2009 16:31:31

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

middle tier

RPyC
Pyro
Мне RPyC больше нравиться.
Но, как всегда, серебрянной пули нет, и мозг включать нужно в любом случае.



Офлайн

#6 Апрель 9, 2009 17:32:30

j2a
От:
Зарегистрирован: 2006-06-29
Сообщения: 869
Репутация: +  1  -
Профиль   Отправить e-mail  

middle tier

Ну я бы использовал кроссплатформенные решения, скрывающие детали реализации app-сервера. Лучше всего, IMHO, REST. XML RPC тож нормально но если “чтобы работало почти прозрачно”, то RPyC хороший вариант. Только да, согласен с Андреем Светловым, нужно не забывать включать мозг.



Офлайн

#7 Апрель 9, 2009 22:00:10

demas
От:
Зарегистрирован: 2008-09-10
Сообщения: 60
Репутация: +  0  -
Профиль   Отправить e-mail  

middle tier

register_function`у кормиш класс, разве так можно, а я яй :\ читай доку!

А что надо было использовать?
Есть register_instance() - но он просто делает на клиент доступными методы экземпляра класса, причем эти меоды не видят переменных класса:

Сервер:

class MyClass:
def __init__(self, a):
self.a = a
def say(self):
return a

server.register_instance(MyClass(100))
Клиент:
import xmlrpclib

s = xmlrpclib.ServerProxy('http://localhost:8000')
s.say()
Результат:

demas@fedora ~/sources/study/python $ python rpc_client.py
Traceback (most recent call last):
File “rpc_client.py”, line 5, in <module>
s.say()
File “/usr/lib/python2.5/xmlrpclib.py”, line 1150, in __call__
return self.__send(self.__name, args)
File “/usr/lib/python2.5/xmlrpclib.py”, line 1440, in __request
verbose=self.__verbose
File “/usr/lib/python2.5/xmlrpclib.py”, line 1204, in request
return self._parse_response(h.getfile(), sock)
File “/usr/lib/python2.5/xmlrpclib.py”, line 1343, in _parse_response
return u.close()
File “/usr/lib/python2.5/xmlrpclib.py”, line 790, in close
raise Fault(**self._stack)
xmlrpclib.Fault: <Fault 1: “<type ‘exceptions.NameError’>:global name ‘a’ is not defined”>



Офлайн

#8 Апрель 9, 2009 22:02:56

demas
От:
Зарегистрирован: 2008-09-10
Сообщения: 60
Репутация: +  0  -
Профиль   Отправить e-mail  

middle tier

Хотя в общем то, я уже свыкся с идеей упаковки экземпляров классов в контейнеры на сервере и воссоздание классов из контейнера на клиенте.
Надо только найти максимально удобный для этого способ.



Офлайн

#9 Апрель 9, 2009 22:04:25

demas
От:
Зарегистрирован: 2008-09-10
Сообщения: 60
Репутация: +  0  -
Профиль   Отправить e-mail  

middle tier

RPyc и Pyro посмотрю.
Спасибо.



Офлайн

#10 Апрель 10, 2009 04:08:35

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

middle tier

j2a
REST - лучший. Но только тема несколько выходит за рамки топика. Поэтому с ходу настоятельно советовать поостерегся.

Проблема для RPyC очень простая: можно не заметить, что твой код уже перелез на сервер и потому жутко тормозит.
Проблема включения мозга - не всегда очевидная. Я уже писал, что пользуясь безнаказанностью pickle пропихивали абсолютно ненужные и избыточные данные через сеть (и удивлялись, почему определенные regression показывают от билда к билду все более плачевные результаты). Могу сказать в свое оправдание лишь одно: это была не моя команда и я за их работой не следил.

Но, тем не менее, с самого начала рекомендовал бы RPyC. А потом можно заменить протокол на более строгий и быстро надавать по рукам тем, кто вообразил себе невесть чего. Если соображалка уже работает, конечно же.

Так мигрировать и обучаться, ИМХО, легче.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version