我正在編寫一個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