2012-12-29 21 views
0

我在使用gen_server,supervisor和mnesia時遇到問題。我有主管:http://pastebin.com/8rkfrq7D 它啓動服務器模塊啓動mnesia。我的問題是,當我寫mnesia不會與主管重啓

erl 
c(superv). 
superv:start_link(). 
//it opens fine 
C^ 
erl 
c(superv). 
superv:start_link(). 
    ** exception exit: shutdown 
//if i try again start_link() it is working 

我明白了。我刪除了負責啓動mnesia的部分,並且它工作正常,所以我期望即時退出(通過ctrl + c)不會正確關閉mnesia。不幸的是,即使我調用mnesia:stop(),在再次調用start_link()之前它會返回異常退出。請幫我解決這個問題。

回答

0

啓動mnesia不完全正確的方式是作爲一個應用程序。

application:start(mnesia). 

在您開始您的應用程序之前。它可以在您開發系統時使用。對於真正的部署,您希望使用引導腳本生成release。發佈是一個獨立的Erlang系統,您可以在外部機器上啓動。您將編寫自己的應用程序,編寫一個my_application_name.app文件,其中包含對mnesia的依賴關係。然後你想生成一個版本,通常使用reltool,然後這個版本將在啓動my_application_name之前啓動mnesia進行初始化。至少這是真正的的方式來做到這一點。

rebar這樣的工具可以幫助您維護您的應用程序和reltool.config文件以構建您的版本。

請注意,Mnesia在啓動之前需要一個模式。一個常見的技巧是讓你的版本包含一個默認的空數據庫,這個數據庫被安裝,以便參數指向它。因此,如果你啓動一個新生成的系統,它有一個數據庫開始。你可以重新從頭開始重新安裝空的數據庫。查看mnesia中的FALLBACK.BUP,瞭解如何做到這一點。

至於你的錯誤,你不能啓動你的服務器兩次。第一次,它在原子server下注冊,所以當它已經運行時的後續重啓將會使其崩潰。如果在啓用SASL應用程序的情況下啓動Erlang,您有時可以獲得提示。無論是執行application:start(sasl)或運行二郎神像這樣:

erl -boot start_sasl 

其替代與也開始SASL變體正常開機腳本。

+0

Thx for answer。我添加了停止功能:[http://pastebin.com/VziRrqEb](我也提供了數據庫初始化函數)。現在,我可以監督start_link(),然後停下來,然後再次啓動它,它就會起作用。但是如果關閉erlang shell。再次打開它並調用start_link()它再次返回異常退出:shutdown(並且顯然如果我調用(錯誤之後)它再次工作)。你能幫我解決這個問題嗎? – aragornsql

+0

是的,我可以:)你的問題是你正在調用mnesia:create_schema()。這隻能執行一次,下次嘗試執行時,它會在init函數的某處失敗。你應該斷言你的mnesia:X調用的答案,以便你知道哪一個失敗。例如'ok = mnesia:start()'。訣竅是創建一個新的空數據庫,然後在每次重新開始時重新安裝這個數據庫。看看我提到的'FALLBACK.BUP'的東西。 –

+0

我不確定這是否正確。我寫過這樣的代碼: case mnesia:start()of ok - > ok; {error,Reason} - > io:format(「Base start:〜p \ n」,[Reason])%,{error,Reason} end 但是不會拋出錯誤。還有什麼更多的我從init刪除create_schema /表,它仍然失敗 – aragornsql