SQLAlchemy's описание расширение, которое становится стандартным в 0,5, обеспечивает все в одном интерфейсе очень как этот Django или Storm. Это также интегрируется беспрепятственно с классами/таблицами, настроенными с помощью стиля datamapper:
Base = declarative_base()
class Foo(Base):
__tablename__ = 'foos'
id = Column(Integer, primary_key=True)
class Thing(Base):
__tablename__ = 'things'
id = Column(Integer, primary_key=True)
name = Column(Unicode)
description = Column(Unicode)
foo_id = Column(Integer, ForeignKey('foos.id'))
foo = relation(Foo)
engine = create_engine('sqlite://')
Base.metadata.create_all(engine) # issues DDL to create tables
session = sessionmaker(bind=engine)()
foo = Foo()
session.add(foo)
thing = Thing(name='thing1', description='some thing')
thing.foo = foo # also adds Thing to session
session.commit()
gen_server
будет иметь незначительные накладные расходы по сравнению с самореализуемыми серверами, потому что для каждого сообщения требуется несколько дополнительных вызовов функций (один из которых является динамическим). Я не думаю, что вам следует учитывать это на этапе реализации. Вы когда-либо передумали, переход с gen_server
на ваш собственный сервер должен быть простым.
Что вы получаете с gen_server
по сравнению с простым циклом:
Я бы также использовал gen_server
. Как только вы воспользуетесь этим средством, вы научитесь ценить его ценность. Обратный вызов функции может быть немного неудобным (например, handle_cast
для асинхронных вызовов), но, в конце концов, вы к нему привыкнете.
Кроме того, я бы посоветовал не заниматься «преждевременной оптимизацией» "без каких-либо испытаний. Вероятно, вы не захотите жертвовать удобочитаемостью / удобством обслуживания ради минимального повышения эффективности.
Я бы выбрал gen_server
просто потому, что было вложено столько усилий, чтобы заставить его работать правильно при различных обстоятельствах. Он заботится о деталях, которые трудно исправить. Я полагаю, что gen_server
может добавить некоторые накладные расходы, но я перестал давать советы по производительности. Если вам действительно интересно, примените оба варианта и измерьте скорость - это единственный верный способ узнать.
Вы также можете использовать gen_server2 ребята, стоящие за RabbitMQ.
Это похоже на gen_server, за исключением следующих настроек (из комментариев):
1) the module name is gen_server2
2) more efficient handling of selective receives in callbacks
gen_server2 processes drain their message queue into an internal
buffer before invoking any callback module functions. Messages are
dequeued from the buffer for processing. Thus the effective message
queue of a gen_server2 process is the concatenation of the internal
buffer and the real message queue.
As a result of the draining, any selective receive invoked inside a
callback is less likely to have to scan a large message queue.
3) gen_server2:cast is guaranteed to be order-preserving
The original code could reorder messages when communicating with a
process on a remote node that was not currently connected.
Исходя из вашего вопроса, я предполагаю, что вы пишете более «постоянный» сервер.
В общем, развертывание собственного сервера более универсально и немного быстрее, если вы все правильно поняли. Но, и это большой НО:
Вам придется все делать самостоятельно, что увеличивает риск ошибок!
Если вы хотите, чтобы вашим сервером управляли OTP-способом, который вы, вероятно, делаете, если вы создаете надежную систему, тогда вам также придется справиться со всем этим самостоятельно. И сделайте это правильно.
Если бы я делал постоянный сервер, я бы начал использовать gen_server
и только откатился бы и откатил свой собственный, если бы столкнулся с серьезными трудностями при реализации того, что мне нужно.
Короче. живые серверы - другое дело.