Skip to content
This repository

Manual OTP project w two apps 

dwagner4 edited this page · 3 revisions

Instructions for creating a release manually with two applications. Regretfully, I can get the apps built, but the release has never come together.
You will need Emacs with the erlang-mode

Build the file structure. (OTP in Action p.121)

.
└── lib
    ├── app1
    │   ├── doc
    │   ├── ebin
    │   ├── include
    │   ├── priv
    │   └── src
    └── app2
        ├── doc
        ├── ebin
        ├── include
        ├── priv
        └── src

build the basic gen_servers which will serve as the functionality of the apps. In Emacs create a new file called lib/app2/src/app1_server.erl. From the "Erlang" menu at the bottom of Emacs, select the gen_server skeleton. (OTP in Action p.98) add the following,

%% API
-export([start_link/0,
     sayhello/0]).

then add

start_link() ->
    gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).

sayhello() ->
    gen_server:call(?MODULE, {sayhello}).

finally

handle_call({sayhello}, _From, State) ->
    io:format("hello from app1~n"),
    Reply = ok,
    {reply, Reply, State};
handle_call(_Request, _From, State) ->
    Reply = ok,
    {reply, Reply, State}.

Do the same creating lib/app2/src/app2_server.erl

Create lib/app1/src/app1_sup.erl. Open a file in Emacs and use the supervisor skeleton. modify the init() function with (OTP in Action p.124)

App = {app1_server, {app1_server, start_link, []},
          Restart, Shutdown, Type, [app1_server]},

{ok, {SupFlags, [App]}}.

create another supervisor in app2

then make lib/app1/src/app1_app.erl Again, use the Application skeleton in Emacs. (OTP in Action p.126)

start(_StartType, _StartArgs) ->
    case app1_sup:start_link() of
        {ok, Pid} ->
            {ok, Pid};
        Error ->
            Error
    end.

Create another one for app2

finally create lib/app1/ebin/app1.app file which is a single tuple. (OTP in Action p.122)

{application, app1,
 [{description, "a pointless demo app"},
  {vsn, "0.1.0"},
  {modules, [app1_app,
             app1_sup,
             app1_server]},
  {registered, [app1_sup]},
  {applications, [kernel, stdlib]},
  {mod, {app1_app, []}}
]}.

Do the same for app2

Should have this structure

.
└── lib
    ├── app1
    │   ├── doc
    │   ├── ebin
    │   │   └── app1.app
    │   ├── include
    │   ├── priv
    │   └── src
    │       ├── app1_app.erl
    │       ├── app1_server.erl
    │       └── app1_sup.erl
    └── app2
        ├── doc
        ├── ebin
        │   └── app2.app
        ├── include
        ├── priv
        └── src
           ├── app2_app.erl
           ├── app2_server.erl
           └── app2_sup.erl

Regretfully I can't reliably make releases. However, one can run these apps in the following manner.

Manual_OTP$ erlc -o lib/app1/ebin lib/app1/src/*.erl
Manual_OTP$ erlc -o lib/app2/ebin lib/app2/src/*.erl
Manual_OTP$ erl -pa lib/*/ebin
Erlang R15B03 (erts-5.9.3) [source] [64-bit] [smp:2:2] [async-threads:0] [kernel-poll:false]

Eshell V5.9.3  (abort with ^G)
1> application:start(app1).
ok
2> app1_server:sayhello().
hello from app1
ok
3> application:start(app2).
ok
4> app2_server:sayhello().
hello from app2
ok
5> 
Something went wrong with that request. Please try again.