8

我有一个用 Erlang 制作的服务器应用程序。在其中我有一个记忆表,用于存储有关照片的一些信息。本着“一切都是过程”的精神,我决定将该表包装在一个gen_server模块中,以便该 gen_server模块是唯一直接访问该表的模块。通过向该进程(具有注册名称)发送消息来完成向该表的查询和添加信息。这个想法是会有几个客户端进程从该表中查询信息。

这工作得很好,但该gen_server模块没有状态。它所需的一切都存储在 mnesia 表中。所以,我想知道 agen_server是否可能不是封装该表的最佳模型?

我是否应该不让它成为一个过程,而只是通过该模块中的函数封装表格?如果该模块中出现错误,这将导致调用进程崩溃,我认为这可能会更好,因为它只会影响单个客户端,而不是现在,当它会导致 gen_server进程崩溃时,让每个人都无法访问表(直到主管重新启动它)。

非常感谢任何输入。

4

3 回答 3

10

我猜根据奥卡姆剃刀没有必要gen_server存在这个,特别是因为其中绝对没有存储状态。当您需要严格按顺序访问表(或任何其他资源)时(例如,您可能希望以瓶颈为代价避免任何中止的事务),可能需要这样的过程。

将对表的访问封装在一个模块中是一个很好的解决方案。它不会产生额外的复杂性,同时提供适当的抽象和封装级别。

于 2009-09-17T09:16:37.290 回答
6

我不确定我是否理解您为什么决定用流程封装表格。Mnesia 旨在调解对表的多个并发访问,包括本地和分布在集群中的表。

创建一个执行所有特定表访问操作和更新的 API 模块是一个好主意,因为 API 函数将在调用它们的代码中更好地传达您的意图。它比将 mnesia 操作直接放入调用代码中更具可读性。

如果需要,API 模块还为您提供了稍后从 mnesia 切换到其他存储系统的选项。在 API 模块中使用 mnesia 事务可以保护您免受一些编程错误的影响,因为 mnesia 将回滚崩溃的操作。API 模块将始终可供调用者使用,并允许任意数量的调用者同时执行操作,而基于 gen_server 的 API 有一个故障点,即进程,它可以使 API 不可用。

基于 gen_server 的 API 为您提供的唯一功能是序列化对表的访问 - 这是一个不寻常的要求,除非您特别需要它,否则它将成为性能杀手。

于 2009-09-17T15:59:34.697 回答
0

当您想要使用脏访问并避免事务时,使用单个 gen_server 进程处理 mnesia 表可能是一个好主意。这种方法可能比 txs 更快,但通常您需要对其进行基准测试。

于 2014-05-21T12:02:27.310 回答