2009-09-17 41 views
8

我有一個在Erlang製作的服務器應用程序。其中我有一個mnesia表 ,存儲一些照片信息。本着「一切都是 過程」的精神,我決定將該表包裝在gen_server模塊中,以便 gen_server模塊是唯一直接訪問該表的模塊。查詢 並向該表添加信息是通過向該進程 (其具有註冊名稱)發送消息來完成的。這個想法是將有幾個客戶端進程查詢來自該表的信息。使用gen_server封裝mnesia表?

這工作得很好,但gen_server模塊沒有狀態。它所要求的一切都存儲在mnesia表中。所以,我想知道gen_server可能不是封裝該表的最佳模型嗎?

我是不是應該讓它成爲一個進程,而只是通過該模塊中的函數封裝表 ?如果該模塊中存在錯誤,那麼 會導致調用進程崩潰,我認爲這可能會更好,因爲 它只會影響單個客戶端,而不是現在,這會導致進程到達 gen_server進程導致每個人都無法訪問表格(直到主管重新啓動 ))。

任何輸入,非常感謝。

回答

9

我想根據Occam's razor沒有必要爲此gen_server存在,特別是因爲有絕對未存儲狀態。當您需要訪問表(或任何其他資源)爲嚴格順序(例如,您可能想要避免以瓶頸爲代價的任何中止事務)時,可能需要此過程。

模塊中封裝對錶格的訪問是一個很好的解決方案。它創建了沒有額外的複雜性,同時提供適當的水平的抽象和封裝。

6

我不確定我明白你爲什麼決定用一個進程封裝一個表。 Mnesia旨在調解多個併發訪問表,無論是在本地還是分佈在一個集羣中。

創建一個執行所有特定表訪問操作和更新的API模塊是一個好主意,因爲API函數會更好地在調用它們的代碼中傳達您的意圖。它比將mnesia操作直接放入調用代碼更具可讀性。

如果需要,API模塊還可以讓您在以後從mnesia切換到其他存儲系統。在你的API模塊中使用mnesia事務可以保護你免受一些程序錯誤的困擾,因爲mnesia會回滾崩潰的操作。 API模塊將始終可供調用者使用,並允許任意數量的調用者同時執行操作,而基於gen_server的API具有可導致API不可用的失敗點。

基於gen_server API通過純功能性API提供的唯一功能是序列化對錶的訪問 - 這是一個不尋常的要求,除非您特別需要它,否則它將成爲性能殺手。

0

當您想使用髒訪問並避免事務時,使用單個gen_server進程處理mnesia表可能是一個好主意。這種方法可能比txs更快,但通常你需要對它進行基準測試。