使用gen_server封装mnesia表?

发布于 2024-08-04 13:13:04 字数 486 浏览 12 评论 0原文

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

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

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

任何意见都将受到高度赞赏。

I have a server application made in Erlang. In it I have an mnesia table
that store some information on photos. In the spirit of "everything is a
process" I decided to wrap that table in a gen_server module, so that the
gen_server module is the only one that directly accesses the table. Querying
and adding information to that table is done by sending messages to that process
(which has a registered name). The idea is that there will be several client
processes querying information from that table.

This works just fine, but that gen_server module has no state. Everything it
requires is stored in the mnesia table. So, I wonder if a gen_server is perhaps
not the best model for encapsulating that table?

Should I simply not make it a process, and instead only encapsulate the table
through the functions in that module? In case of a bug in that module, that
would cause the calling process to crash, which I think might be better, because
it would only affect a single client, as opposed to now, when it would cause the
gen_server process to crash, leaving everyone without access to the table (until
the supervisor restarts it).

Any input is greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小女人ら 2024-08-11 13:13:04

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

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

I guess according to Occam's razor there is no need for this gen_server to exist, especially since there is absolutely no state stored in it. Such process could be needed in situations when you need access to the table (or any other resource) to be strictly sequential (for example you might want to avoid any aborted transactions at cost of a bottleneck).

Encapsulating access to the table in a module is a good solution. It creates no additional complexity, while providing proper level of abstraction and encapsulation.

三生池水覆流年 2024-08-11 13:13:04

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

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

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

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

I'm not sure I understand why you've decided to encapsulate a table with a process. Mnesia is designed to mediate multiple concurrent accesses to tables, both locally and distributed across a cluster.

Creating an API module that performs all the particular table access operations and updates is a good idea as the API functions will convey your intent better in the code that calls them. It will be more readable than putting the mnesia operations directly into the calling code.

An API module also gives you the option to switch from mnesia to some other storage system later if you need to. Using mnesia transactions inside your API module protects you from some programming errors as mnesia will roll-back operations that crash. The API module will always be available to callers and allows any number of callers to perform operations concurrently, whereas a gen_server based API has a point of failure, the process, that can render the API unavailable.

The only thing a gen_server based API gives you over a pure-functional API is to serialize access to the table - which is an unusual requirement and unless you specifically need it, it will be a performance killer.

青萝楚歌 2024-08-11 13:13:04

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

It may be a good idea to handle a mnesia table using single gen_server process when you want to use dirty access and avoid transactions. This approach might be faster than txs, but as usually you need to benchmark it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文