使用 gen_server 封装一个 mnesia 表?
Posted
技术标签:
【中文标题】使用 gen_server 封装一个 mnesia 表?【英文标题】:Using gen_server to encapsulate an mnesia table? 【发布时间】:2010-11-29 01:51:35 【问题描述】:我有一个用 Erlang 制作的服务器应用程序。在里面我有一个记忆表
存储照片上的一些信息。本着“一切都是
过程”我决定将该表包装在 gen_server
模块中,以便
gen_server
模块是唯一直接访问表的模块。查询
并向该表添加信息是通过向该进程发送消息来完成的
(具有注册名称)。这个想法是会有几个客户
处理从该表查询信息。
这很好用,但是 gen_server
模块没有状态。一切它
requires 存储在 mnesia 表中。所以,我想知道gen_server
是否可能是
不是封装该表的最佳模型?
我是不是应该干脆不让它成为一个过程,而只是封装表格
通过该模块中的功能?如果该模块中出现错误,则
会导致调用进程崩溃,我认为这可能会更好,因为
它只会影响单个客户,而不是现在,当它会导致
gen_server
进程崩溃,让每个人都无法访问表(直到
主管重新启动它)。
非常感谢任何输入。
【问题讨论】:
【参考方案1】:我猜根据Occam's razor,没有必要存在这个gen_server
,尤其是因为其中绝对没有状态存储。当您需要以严格顺序访问表(或任何其他资源)时(例如,您可能希望避免任何中止的事务在瓶颈成本)。
在模块中封装对表的访问是一个很好的解决方案。它不会产生额外的复杂性,同时提供了适当的级别的抽象和封装。
【讨论】:
【参考方案2】:我不确定我是否理解您为什么决定用进程封装表格。 Mnesia 旨在调解对表的多个并发访问,包括本地和分布在集群中。
创建一个执行所有特定表访问操作和更新的 API 模块是一个好主意,因为 API 函数将在调用它们的代码中更好地传达您的意图。它比将 mnesia 操作直接放入调用代码中更具可读性。
如果需要,API 模块还为您提供了稍后从 mnesia 切换到其他存储系统的选项。在 API 模块中使用 mnesia 事务可以保护您免受一些编程错误的影响,因为 mnesia 将回滚崩溃的操作。 API 模块将始终可供调用者使用,并允许任意数量的调用者同时执行操作,而基于 gen_server 的 API 有一个故障点,即进程,可能会导致 API 不可用。
基于 gen_server 的 API 为您提供的唯一功能是序列化对表的访问 - 这是一个不寻常的要求,除非您特别需要它,否则它将成为性能杀手。
【讨论】:
【参考方案3】:当您想要使用脏访问并避免事务时,使用单个 gen_server 进程处理 mnesia 表可能是一个好主意。这种方法可能比 txs 更快,但通常您需要对其进行基准测试。
【讨论】:
以上是关于使用 gen_server 封装一个 mnesia 表?的主要内容,如果未能解决你的问题,请参考以下文章
是否可以使用 Erlang、Mnesia 和 Yaws 开发强大的网络搜索引擎?