2016-04-22 6 views
2

私はrebar3を使用してリリースを作成していますが、運用時にmnesiaを初期化するにはどうすればよいですか?生産上のmnesiaをどのように初期化しますか?

mnesia:create_schema([node()])を実行する「インストール」エスケープを書くと、リリースで使用されているノード名とは全く異なるノード名が使用されます。

私はで私のアプリケーションを起動するときに生産mnesiaが "myapp @ localhost"ノードにアクセスしようとしている間、 "nonode @ nonode"のスキーマを作成することになります。

また、それは鶏と卵の問題のようなものがある:私は

  • 私は私のアプリを実行せずに私のmnesiaテーブルをインストールすることはできませんmnesiaテーブルずに私のアプリを起動することはできません

    1. (アプリと同じ名前のnode()が使用されます)。

    これを処理する良い方法がある場合は、単に放浪していますか?

    #!/usr/bin/env escript 
    %% -*- erlang -*- 
    %%! -smp enable ls-mnesia debug verbose 
    -include("../include/rr.hrl"). 
    
    main(_) -> 
        application:set_env(mnesia, dir, "/usr/local/src/db/mnesia"), 
        application:stop(mnesia), 
        install([node()|nodes()]). 
    
    install(Nodes) -> 
        case mnesia:create_schema(Nodes) of 
         ok -> 
          rpc:multicall(Nodes, application, start, [mnesia]), 
          read_store_create_tables(Nodes), 
          event_store_create_tables(Nodes), 
          rpc:multicall(Nodes, application, stop, [mnesia]); 
         Err -> 
          error_logger:warning_msg("Could not create schema: ~p~n", [Err]), 
          Err 
        end.  
    
    event_store_create_tables(Nodes) -> 
        {_, ok} = mnesia:create_table(rr_events, 
          [{attributes, record_info(fields, rr_events)}, 
          {disc_copies, Nodes}, 
          {type, bag}]). 
    
    read_store_create_tables(Nodes) -> 
        % Initialize the actual data-tables for the projections 
        {_, ok} = mnesia:create_table(rr_competencies, 
          [{attributes, record_info(fields, rr_competencies)}, 
          {disc_copies, Nodes}]). 
    

    がP.S:私はリリースを構築するためにrelxを使用していますrebar3を使用しています:ここで

    は私の私が独立して実行escriptをインストールしています。

  • 答えて

    1

    私は自分自身のbuild systemを使用しています。これは主に、その正確な要件 - ノードをインストールする前にノードを初期化して初期化できるためです。この考え方は非常に単純です:があり、この特定の例ではcmdhumbundeeと呼ばれています。 cmdリリースはメインアプリケーションを起動せず、ロードするだけです。次に、ノードを初期化するために特殊な関数が実行されます。この機能はreltool.configファイルで設定されています。この場合、deployアプリケーションのhbd_setupです。この関数は構成ファイルを読み取り、バックアップからmnesiaデータベースを作成して初期化するか、バックアップが存在しない場合は新しいデータベースを作成します。ノードがインストールされると、適切なリリースを使用して開始されます。同じ手順が開発中(ソースコードから直接)および実働(OTPリリースから)で実行されます。

    この設定では、ほぼ同じコマンドと設定ファイル(builderlreltool.configの設定から生成されます)を使用して、両方のリリースが同じ場所から開始されるため、説明した問題は存在しません。


    は、手動またはスクリプトのいくつかの並べ替えにこれらのステップを実行することで、rebar3relxを含め、任意のビルドツールと同じ考え方を採用することができます。

    builderlは、これらのステップを自動的に実行し、開発や生産において同じ方法で実行する環境を提供します。 bottom of the humbundee project's READMEファイルを参照してください。

    ノードをインストールします。これはcmdリリースを開始し、ノードを初期化するためにhbd_setup:install/2機能を実行します:

    ./bin/init.esh 
    

    スタートノード。しかし、それはリリースを作成するだけでOTPを使用して、

    ./bin/start.esh 
    

    builderlが実際に引っ張るとdependencies that depend on other projectsをコンパイルするrebarを使用しています:これは、対応するスーパーバイザーの木がすべてのアプリケーションを起動するhumbundeeリリースを、開始します。また、project-wide dependency fileを使用して依存関係自体をダウンロードすることもできます。compiled with makemakeがコンパイルされていない場合はwork in progressです)。私はそれが助けて欲しい

    +0

    しかし、このすべての自動化ビルドスクリプト(つまり、有能なもの)をどのように扱うのですか?問題は、開始されるとアプリがスクリプトのようではなく、サービスとして実行されるため、アプリはいつアプリケーションがデータベースを初期化するかを知らないということです。 (うわー、これは想像以上に複雑です) – drozzy

    +0

    この答えをチェックしてください( 'init:stop()'を検索してください):http://stackoverflow.com/questions/36359040/idiomatic-way-to-ship-コマンドラインツールで書かれたerlang/36362156#36362156次にこの関数:https://github.com/yoonka/builderl/blob/master/src/bld_init.erl#L902基本的に2つのErlangインスタンスがあります。 '。/ bin/init.esh'を実行すると、' builderl'はそれ自身のVMで動作します。その後、 'cmd'リリースを使ってインストールされたVMを起動し、それを設定してからシャットダウンします。何か問題が生じた場合は、コード '1'を返します。 'builderl'が終了すると、戻りコードは' make'や他のスクリプトによって検査されます。 – Amiramix

    関連する問題