Erlang: when to perform `inets:start()`?
Asked Answered
P

3

6

What is the appropriate place for performing inets:start() ?

  1. in `applicationname_app' module?
  2. in applicationname_sup supervisor module?
  3. in a child process hanging from the supervisor?\
  4. someplace else?

(I am still struggling with inets:httpd)

Note: the answer cannot be to the tune " use a boot file " , please.

Pyrrho answered 3/12, 2009 at 13:27 Comment(0)
I
5

inets is a "stand-alone" Erlang application; inets:start() is just an alias to application:start(inets). I guess the answer pretty much depends on how you maintain your code.

If your code is packaged as an application, your .app file should list inets as required to be started before yours (see the applications tag). Starting your applicaion with application:start(my_app). will now ensure that inets is also started. Consequence: if you make a boot file, it will also start inets for you :-P

If you are keen on not using applications, I guess the choice depends on how your code works. If you will always need inets to be started, it is better started by any of your supervisors. If it is rarely needed, you can always make sure it is started with something like:

ensure_app_started(App) ->
  case application:started(App) of
    ok -> ok;
    {error, already_started} -> ok;
    Error -> Error
  end.
Instrumental answered 3/12, 2009 at 14:47 Comment(4)
@zed: thanks again. Let's say I were to package my app as an application, how would I start it from the command line? (I am mostly doing daemons).Pyrrho
@zed: i.e. erl -sname daemon -detached -boot start_sasl -s daemon_app start? Show me an example, please.Pyrrho
Add SASL to the application dependencies as well. Make a release file, and then a boot script. Then -boot my_boot.Instrumental
@Zed: I finally decided to restructure and go OTP all the way (almost- no boot files!). I went for a proper .app based structure. Thanks for your time.Pyrrho
A
1

In 2019, we use rebar3 to create an application and manage its dependencies. For dependencies that need to be downloaded, you add them to rebar.config, and rebar3 will download the dependencies. For example, if you add hackney (an http client) to rebar.config:

{erl_opts, [debug_info]}.
{deps, [
  {hackney, ".*", {git, "git://github.com/benoitc/hackney.git", {branch, "master"}}}
]}.

{shell, [
  % {config, "config/sys.config"},
    {apps, [http_client]}
]}.

Then do:

../your_app_name$ rebar3 compile

rebar3 will download hackney and compile all the files in the application.

To make sure that all your dependencies get started before your app, you add the names of the dependencies to:

src/your_app_name.app.src

For instance,

{application, http_client,
 [{description, "An OTP application"},
  {vsn, "0.1.0"},
  {registered, []},
  {mod, {http_client_app, []}},
  {applications,
   [kernel,
    stdlib,
    hackney    %%%<=========HERE
   ]},
  {env,[]},
  {modules, []},

  {licenses, ["Apache 2.0"]},
  {links, []}
 ]}.

The actual .app file gets created here:

_build/default/lib/your_app_name/ebin/your_app_name.app

To start your app in the shell along with all its dependencies, you do:

../your_app_name$ rebar3 shell 

The inets application comes with erlang, so it doesn't need to be downloaded, so you don't specify inets as a dependency in rebar.config (you'll get an error when you $ rebar3 compile). You still need to specify inets as a dependency in your application in the file:

src/your_app_name.app.src

But rebar3 itself uses inets (to download your dependencies), so even if you didn't specify inets as a dependency in your application, inets would still get started before your app. You can test that by not specifying inets as a dependency in your application, then doing:

$ rebar3 shell
...
...
1> application:start(inets)
{error,{already_started,inets}}

But, don't rely on that and DO specify inets as a dependency in your application.

Acnode answered 21/5, 2019 at 3:36 Comment(0)
R
0

If your code is packaged as an application, list inets in the application resource file:

% Filename: ebin/flamingo.app
{application, flamingo,
  [{vsn, "1.0.0"},
   {modules, [flamingo_app,
              flamingo_sup,
              flamingo]},
   {applications, [kernel,
                   stdlib,
                   inets]},
   {mod, {flamingo_app, []}}
  ]}.

Then you can start the application using application:ensure_all_started(flamingo). This ensures that inets is started automatically for you (i.e. there is no need to explicitly call inets:start()).

For example (assuming the *.app file and *.beam files and are in ebin/):

$ erl -pa ebin/
Eshell V9.2  (abort with ^G)
1> application:ensure_all_started(flamingo).
{ok,[inets,flamingo]}
Reorganize answered 20/5, 2019 at 18:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.