我正在编写一个ejabberd模块,用户控制何时将消息发送给接收者而不是立即发送(如提前发送的生日祝福)。这是通过添加自定义XML元素的消息节像下面Mnesia数据库设计用于存储将来需要发送的消息
<message xmlns="jabber:client" from="[email protected]" to="[email protected]/32375806281445450055240436" type="chat">
<schedule xmlns="ank" year="2015" month="10" day="19" hour="22" minute="36" second="13"/>
<body>hi</body>
</message>
现在这些计划的消息,必须存储在Mnesia数据库和发送给收件人当时间到达完成。
方法1: 一种方法是创建一个表为每个用户,当收到消息,存储消息到用户表,并设置一个计时器来处理 消息,并删除时像下面的做示例代码
timer:apply_after(SecondsDelay, ?MODULE, post_message_delete, [TableName, RecordUniqueKeyHash, From, To, Packet]).
的post_message_delete方法将发送该消息的定时器超时使用路由方法显示在以下和删除Mnesia数据库记录后,当被调用。
ejabberd_router:route(From, To, Packet)
由于mnesia中表的数量限制,为每个用户创建表是不可行的。
方法2: 另一种方法是所有的用户的消息存储在一个单独的表,并作为消息到达并且一旦处理消息删除它设置为每一个消息中的计时器(与上述相同)。
使用mnesia数据库的整个想法是在ejabberd服务器崩溃的情况下可靠地处理消息。
为了达到这个目的,我们在每条消息的记录中使用一个pid字段。每个消息记录都有一个pid字段,其中包含正在处理此消息的进程的pid。最初,它是未定义的(当消息到达filter_packet挂钩时),但在生成消息处理方法后,它将更新mnesia数据库中的记录中的pid。
因此,如果服务器在模块启动方法重新启动时崩溃,则所有消息都会迭代并检查pid是否处于活动状态(is_process_alive),如果没有活动,则会在消息中产生处理方法,处理消息并删除一次。
缺点 这种方法的缺点是,即使消息必须在未来(下个月或明年)仍然是一个进程正在运行此消息远交付并有运行的尽可能多的进程有尽可能多的消息。
方法3:
要在来到方法二的缺点,扫描数据库每隔一小时,并积累有下一个小时,仅投放和处理它的消息。
这种方法的缺点是数据库每小时扫描一次可能会影响性能。
方法4:
要在来到方法3的性能,我们可以为每一个YEAR_MONTH表和产卵只对当前月表的消息处理函数。
什么其他方法最适合使用mnesia数据库的这种用例?
我相信这个问题可能是基于堆栈溢出的一种观点,但可以在http://programmers.stackexchange.com中找到,因为他们的帮助中心指出[“软件架构和设计”](http://programmers.stackexchange .com/help/on-topic)在那里。这个问题实际上并不是erlang特有的。 – Lol4t0
@ Lol4t0指其他网站时,它往往是有帮助的那点(http://meta.stackexchange.com/tags/cross-posting/info) – gnat
@gnat [交叉张贴是令人难以接受的],嘿嘿!但这仍然不意味着问题不会移到正确的地方!如果你有重复的_wrong place_职位应该被删除。 – Lol4t0