<!DOCTYPE html><html><head>
<style type="text/css">body { font-family:'Helvetica'; font-size:12px}</style>
</head>
<body><div>Hi,</div><div><br></div><div>During a takeover your application is first started on the new node, then stopped on the old one. In between, it runs simultaneously on both of them. The idea is that you can take over the runtime state from the old instance this way. The downside is that you need to be more careful with global name registrations and use e.g. start phases.</div><div><br></div><div>See this post for a much better, detailed explanation: <a href="http://erlang.org/pipermail/erlang-questions/2011-March/057323.html">Re: Distributed application takeover</a></div><div><br></div><div>BR,</div><div>Daniel</div><div><br></div><div>PS: I would avoid using distributed applications in production. The dist_ac module in the kernel application that takes care of deciding where to run which distributed application is a terrible spaghetti of gen_server callbacks and ad-hoc message passing with tons of race conditions that can block your entire cluster from starting up any distributed apps. I run into about 3-4 different bugs of this kind before abandoning the idea of using this feature.</div><div><br></div><div>On Sun, 01 Dec 2013 16:19:25 -0000, Tyron Zerafa <tyron.zerafa@gmail.com> wrote:<br></div><br><blockquote style="margin: 0 0 0.80ex; border-left: #0000FF 2px solid; padding-left: 1ex"><div dir="ltr">Hi all,<div> </div><div>    I am trying to understand how to implement takeover in Erlang by following the example presented <a href="http://learnyousomeerlang.com/distributed-otp-applications">here</a>. Basically, I am creating the application's supervisor as follows;</div>
<div> </div><div><div><div>start(normal, []) -></div><div><span class="" style="white-space:pre">   </span>m8ball_sup:start_link();</div><div>start({takeover, _OtherNode}, []) -></div><div><span class="" style="white-space:pre">     </span>m8ball_sup:start_link().</div>
</div><div><br></div><div><br></div><div><u>Supervisor init code:</u></div><div><div>start_link() -></div><div><span class="" style="white-space:pre">   </span>supervisor:start_link({global,?MODULE}, ?MODULE, []).</div></div>
<div><br></div><div><u>Supervisor child Specification:</u></div><div><div>{</div><div><span class="" style="white-space:pre">               </span>{one_for_one, 1, 10},</div><div><span class="" style="white-space:pre">              </span>[</div>
<div><span class="" style="white-space:pre">                    </span>{m8ball,</div><div><span class="" style="white-space:pre">                   </span>{m8ball_server, start_link, []},</div><div><span class="" style="white-space:pre">                   </span>permanent,</div>
<div><span class="" style="white-space:pre">                    </span>5000,</div><div><span class="" style="white-space:pre">                      </span>worker,</div><div><span class="" style="white-space:pre">                    </span>[m8ball_server]</div><div><span class="" style="white-space:pre">            </span>}]</div>
<div><span class="" style="white-space:pre">    </span>}</div></div><div><br></div><div><u>Child (m8ball_server) Initialization</u></div><div><div>start_link() -></div><div><span class="" style="white-space:pre">   </span>gen_server:start_link({global, ?MODULE}, ?MODULE, [], []).</div>
</div><div><br></div><div><br></div><div>Consider the following scenario; an Erlang cluster is composed of two nodes A and B with application m8ball running on A. </div><div>Failover works perfect, I'm managing to kill node A and see the application running on the next node, B. </div>
<div>However, when I try to put back up node A (which have a higher priority then B) and init the app, I am getting the following error. I'm assuming that this occurs because node B already contains a supervisor globally registered with that name.  </div>
<div><u>Log on Node A </u><br></div><div><div>{error,{{already_started,<2832.61.0>},</div><div>        {m8ball,start,[{takeover,'b@Tyron-PC'},[]]}}}</div><div><br></div><div>=INFO REPORT==== 1-Dec-2013::16:17:32 ===</div>
<div>    application: m8ball</div><div>    exited: {{already_started,<2832.61.0>},</div><div>             {m8ball,start,[{takeover,'b@Tyron-PC'},[]]}}</div></div><div><br></div><div><br></div><div><u>Log on Node B</u></div>
<div><div>=INFO REPORT==== 1-Dec-2013::16:24:55 ===</div><div>    application: m8ball</div><div>    exited: stopped</div><div>    type: temporary</div></div><div><br></div><div>When I tried registering the supervisor locally, I got a similar exception failing to initializing the worker process. However, if I also register this as local, I would not be able to call it from any node using the app name (since it would not be globally registered).</div>
<div><br></div><div><u>Log on Node A </u><u>(Supervisor Registered Locally)</u><br></div><div>{error,</div><div>    {{shutdown,</div><div>         {failed_to_start_child,m8ball,</div><div>             {already_started,<2832.67.0>}}},</div>
<div>     {m8ball,start,[{takeover,'b@Tyron-PC'},[]]}}}</div><div><br></div><div> </div><div>Any pointers?</div><div><br></div>-- <br>Best Regards,<div>Tyron Zerafa</div>
</div></div>
</blockquote><br><br><br></body></html>