Four ways to start mnesia in OTP environment. Which one should one use?

View: New views
6 Messages — Rating Filter:   Alert me  

Four ways to start mnesia in OTP environment. Which one should one use?

by Sergey Samokhin-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello.

I've found four ways to start mnesia in OTP environment. Which one
should I use? I was a bit puzzled to decide which of them is better.

1) Boot scripts

It seems to be the default approach when it comes to making sure that
all the dependencies of your app will be started.

But there are some disadvantages which make it quite difficult to use
boot scripts as some kind of "dependencies controller":

[-] Runtime doesn't give you a standard way to prepare the system
before a dependency has been started. E.g. it isn't possible for me to
ensure that a directory pointed by "-mnesia dir" is really exist
before mnesia has been started. To make sure that the appropriate
directory exists I have to move the corresponding code to my
escript-based CLI. I don't think a developer will be happy to know
that such a part of code as checks is no longer part of an Erlang
Application. This code can't be executed if the application is started
manually under the fresh erl-shell.
[-] If you use a boot script you have to generate a new one for every
OTP release your application is supposed to work with.
[-] Mnesia isn't automatically stopped after you application has been
terminated. I'm not sure if it's a problem, but if one is going to
start another application which is supposed to use mnesia in the same
VM, it's a good idea to restart mnesia with a fresh schema generated.

2) erl -run mnesia

To start mnesia one can also decide to use either "-run" or "-s"
parameters to erl. Disadvantages of this approach are the same as of
the previous one except that in this case you don't have to regenerate
boot scripts every time you upgrade your erlang package (because there
is no any boot scripts =).

3) From init/1 function of a gen_server using mnesia.

You just write something like this to control when mnesia is started:

init(_) ->
    mnesia:start(),
    %...

[-] It seems a good solution, but you can't stop mnesia in terminate/1
function (mnesia:stop() call hangs). It seems a bit inconsistent to
leave mnesia running after your application has been stopped.

4) Start mnesia as included application

Although how to work with Included Applications is described in OTP
Design Principles I don't see this way being used widely. Maybe
because of the following questions:

[-] Is it safe to start mnesia as included application by starting
mnesia_sup:start/0 from standard OTP supervsor?
[-] Is it safe to set mnesia options (like dir) using set_env before
your_sup:init() has been returned?

Although I've noted only disadvantages (it's more difficult for me to
estimate advantages of those ways right now) I try to use them all.
Which one do you prefer and why?

Thanks.

--
Sergey Samokhin

________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: Four ways to start mnesia in OTP environment. Which one should one use?

by Steve Davis-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Since nobody else has taken this up this holiday weekend, here's my
take:

1) When you intend to stop mnesia -- how are you sure that it's not
being used by another application?
2) Why would you stop your application (apart for development purposes
or decommissioning)?
3) Since Mnesia is an entire subsystem you could either put it in your
application/applications requirement or ensure it's started in the
application/mod supervisor startup call.

That's my take - I'm sure others have more/better suggestions.

BR,
/sd

________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: Four ways to start mnesia in OTP environment. Which one should one use?

by Ulf Wiger-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Sergey Samokhin wrote:

> Hello.
>
> I've found four ways to start mnesia in OTP environment. Which one
> should I use? I was a bit puzzled to decide which of them is better.
>
> 1) Boot scripts
> [...]
>
> [-] Runtime doesn't give you a standard way to prepare the system
> before a dependency has been started. E.g. it isn't possible for me to
> ensure that a directory pointed by "-mnesia dir" is really exist
> before mnesia has been started.

The conventional way to deal with this is to require
an explicit install phase.

One way to accomplish this is to create an application
that starts before mnesia. The way to ensure that it runs
before mnesia when using a boot script is to list the
application before mnesia in the .rel file. The script
builder may adjust the order of applications based on
dependencies, but it will not reorder applications un-
necessarily. Thus, if you put an application before mnesia,
and it doesn't depend on mnesia, it will start before it.

This app can check whether the system has been installed,
or bootstrap the installation otherwise. It could also
check e.g. whether the node has restarted due to partitioned
network, and try to figure out whether to set master nodes
in mnesia, or perhaps whether it should simply wait for
some condition to be fulfilled before letting mnesia synch
with the others.


> [-] If you use a boot script you have to generate a new one for every
> OTP release your application is supposed to work with.

Well, yes, but erlc will do that for you. The pain is that
you have to generate a new .erl file, as the application
versions are listed in it. The 'builder' contrib that I
wrote years ago addressed that, and I believe that Sinan/Faxien
does that too. http://www.erlware.org

> [-] Mnesia isn't automatically stopped after you application has been
> terminated. I'm not sure if it's a problem, but if one is going to
> start another application which is supposed to use mnesia in the same
> VM, it's a good idea to restart mnesia with a fresh schema generated.

This sounds like you really have two independent applications
that do /not/ need to run in the same VM.

Why do you want to reuse the VM instance?
I'd shut down the erlang node in an orderly fashion, and
start a new one, using a different boot script and
a different mnesia dir.

BR,
Ulf W
--
Ulf Wiger
CTO, Erlang Training & Consulting Ltd
http://www.erlang-consulting.com

________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: Re: Four ways to start mnesia in OTP environment. Which one should one use?

by Sergey Samokhin-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello, Steve.

Thanks for your answer.

> 1) When you intend to stop mnesia -- how are you sure that it's not
> being used by another application?

It's often possible, though it may require some additional steps to
take. There is at least one way to ensure that all of your
applications using mnesia terminated before mnesia has been stopped:
every application you start has to write #app{app = AppName, node =
node()} record during the initialization. Later you will be able to
check if some of the allowed applications are still running by looking
at #app{} records present in mnesia.

It only works if applications you're trying to "ping" that way are
written in a uniform manner, i.e. register themself through
mnesia:write(AppRecord). There must be also a corresponding function
unregistering dead apps in a safe/distributed manner. I don't think it
will be possible if one has decided to start mnesia as Included
Applcation.

> 2) Why would you stop your application (apart for development purposes
> or decommissioning)?

To dynamically reconfigure a cluster: add and remove some applications
on the fly. But I don't know what I should answer to "Why do you want
to stop mnesia?" =) Maybe because of the thought that all dependencies
one has started in init/1 has to be stopped in terminate/1.

> 3) Since Mnesia is an entire subsystem you could either put it in your
> application/applications requirement or ensure it's started in the
> application/mod supervisor startup call.

Does this mean that Included application is a wrong way?

--
Sergey Samokhin

________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: Four ways to start mnesia in OTP environment. Which one should one use?

by Sergey Samokhin-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello, Ulf.

> The conventional way to deal with this is to require
> an explicit install phase.

I'll try it, thanks!

> The 'builder' contrib that I wrote years ago addressed that, and I
> believe that Sinan/Faxien does that too. http://www.erlware.org

Thanks again! :]

> This sounds like you really have two independent applications
> that do /not/ need to run in the same VM.

Yeah, it is (details are below). It looks like I don't have to stop
mnesia when an app is terminating.

> Why do you want to reuse the VM instance?
> I'd shut down the erlang node in an orderly fashion, and
> start a new one, using a different boot script and
> a different mnesia dir.

Let me explain what I was thinking about when writing the first letter:

Let's suppose you need to write a few applications which are supposed
to work in a cluster and be added/removed regardless of which
applications are already running: 'FrontEnd', 'BackEnd',
'WebInterface', 'Monitoring'. The obvious solution to make a cluster
is by using mnesia as a kind of foundation.

{first_machine, ['FrontEnd', 'WebInterface']}
{second_machine, ['BackEnd', 'Monitoring']}

Next question is "How should I split applications across VMs?"

There are two answers:

*one VM - one application*
That is what I'm using now. I.e. all applications are started in their own VMs

vs

*One VM - many applications*
I've never tried it, but maybe it's a more convenient way? And here it
would be cool to stop all the dependencies of an application (but not
mnesia, because it's used to connect nodes together).

--
Sergey Samokhin

________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org


Re: Four ways to start mnesia in OTP environment. Which one should one use?

by Paul Mineiro :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I ended up going with #4, included application, on a large project and was
satisfied.  The mnesia bits were open sourced, you can check out
http://code.google.com/p/schemafinder/ for details.  The main reason for
going with included application was to be able to ensure that nodes were
joining the distributed schema in a reasonable state.

We also started our nodes with a shell script that checked all sorts of
preconditions before invoking erl.  That seems a fact of life to me under
all scenarios (e.g., where are you putting standard out and standard error
from the emulator?).

For a simpler hobby project I'm working on starting mnesia as an app has
been working fine, mnesia is really good about letting you do all sorts of
manipulations while it is running so letting it start on it's own is not
that limiting.

-- p

On Fri, 3 Jul 2009, Sergey Samokhin wrote:

> Hello.
>
> I've found four ways to start mnesia in OTP environment. Which one
> should I use? I was a bit puzzled to decide which of them is better.
>
> 1) Boot scripts
>
> It seems to be the default approach when it comes to making sure that
> all the dependencies of your app will be started.
>
> But there are some disadvantages which make it quite difficult to use
> boot scripts as some kind of "dependencies controller":
>
> [-] Runtime doesn't give you a standard way to prepare the system
> before a dependency has been started. E.g. it isn't possible for me to
> ensure that a directory pointed by "-mnesia dir" is really exist
> before mnesia has been started. To make sure that the appropriate
> directory exists I have to move the corresponding code to my
> escript-based CLI. I don't think a developer will be happy to know
> that such a part of code as checks is no longer part of an Erlang
> Application. This code can't be executed if the application is started
> manually under the fresh erl-shell.
> [-] If you use a boot script you have to generate a new one for every
> OTP release your application is supposed to work with.
> [-] Mnesia isn't automatically stopped after you application has been
> terminated. I'm not sure if it's a problem, but if one is going to
> start another application which is supposed to use mnesia in the same
> VM, it's a good idea to restart mnesia with a fresh schema generated.
>
> 2) erl -run mnesia
>
> To start mnesia one can also decide to use either "-run" or "-s"
> parameters to erl. Disadvantages of this approach are the same as of
> the previous one except that in this case you don't have to regenerate
> boot scripts every time you upgrade your erlang package (because there
> is no any boot scripts =).
>
> 3) From init/1 function of a gen_server using mnesia.
>
> You just write something like this to control when mnesia is started:
>
> init(_) ->
>     mnesia:start(),
>     %...
>
> [-] It seems a good solution, but you can't stop mnesia in terminate/1
> function (mnesia:stop() call hangs). It seems a bit inconsistent to
> leave mnesia running after your application has been stopped.
>
> 4) Start mnesia as included application
>
> Although how to work with Included Applications is described in OTP
> Design Principles I don't see this way being used widely. Maybe
> because of the following questions:
>
> [-] Is it safe to start mnesia as included application by starting
> mnesia_sup:start/0 from standard OTP supervsor?
> [-] Is it safe to set mnesia options (like dir) using set_env before
> your_sup:init() has been returned?
>
> Although I've noted only disadvantages (it's more difficult for me to
> estimate advantages of those ways right now) I try to use them all.
> Which one do you prefer and why?
>
> Thanks.
>
> --
> Sergey Samokhin
>
> ________________________________________________________________
> erlang-questions mailing list. See http://www.erlang.org/faq.html
> erlang-questions (at) erlang.org
>
>


________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org