Permalink
Browse files

Hans Svensson's new gen_leader. Leader election bug solved

  • Loading branch information...
uwiger
uwiger committed Sep 22, 2006
1 parent be5c4ab commit abaf7ee3a01af1a735aaed91d31b2e46f5785ccb
View
@@ -7,13 +7,14 @@ DOCDIR=doc
EDOCDIR="../edoc/ebin"
STOOLSDIR="../syntax_tools/ebin"
XMERLDIR="../xmerl/ebin"
-DOC_OPTS=[{title,"Welcome to gen_leader"}]
+DOCDIR=doc
+DOC_OPTS=[{title,"Welcome to gen_leader"},{hidden,false},{private,false}]
+
+all: all-subdirs docs
-all: all-subdirs
-# Commented out since the new edoc is not yet in jungerl.
-#docs:
-# erl -noshell -pa $(EDOCDIR) -pz $(STOOLSDIR) -pz $(XMERLDIR) -run edoc_run application "'$(APPNAME)'" '"."' '$(DOC_OPTS)' -s erlang halt
+docs:
+ erl -noshell -run edoc_run application "'$(APPNAME)'" '"."' '$(DOC_OPTS)' -s erlang halt
all-subdirs:
@for dir in $(SUBDIRS); do \
@@ -29,67 +29,67 @@ <h2><a name="index">Function Index</a></h2>
<h2><a name="functions">Function Details</a></h2>
<h3><a name="append-3">append/3</a></h3>
-<tt>append(Key, Value, Dict) -> term()
+<tt>append(Key, Value, Dict) -&gt; term()
</tt>
<h3><a name="append_list-3">append_list/3</a></h3>
-<tt>append_list(Key, ValList, Dict) -> term()
+<tt>append_list(Key, ValList, Dict) -&gt; term()
</tt>
<h3><a name="erase-2">erase/2</a></h3>
-<tt>erase(Key, Dict) -> term()
+<tt>erase(Key, Dict) -&gt; term()
</tt>
<h3><a name="fetch-2">fetch/2</a></h3>
-<tt>fetch(Key, Dict) -> term()
+<tt>fetch(Key, Dict) -&gt; term()
</tt>
<h3><a name="fetch_keys-1">fetch_keys/1</a></h3>
-<tt>fetch_keys(Dict) -> term()
+<tt>fetch_keys(Dict) -&gt; term()
</tt>
<h3><a name="filter-2">filter/2</a></h3>
-<tt>filter(Pred, Dict) -> term()
+<tt>filter(Pred, Dict) -&gt; term()
</tt>
<h3><a name="find-2">find/2</a></h3>
-<tt>find(Key, Dict) -> term()
+<tt>find(Key, Dict) -&gt; term()
</tt>
<h3><a name="fold-3">fold/3</a></h3>
-<tt>fold(Fun, Acc0, Dict) -> term()
+<tt>fold(Fun, Acc0, Dict) -&gt; term()
</tt>
<h3><a name="is_key-2">is_key/2</a></h3>
-<tt>is_key(Key, Dict) -> term()
+<tt>is_key(Key, Dict) -&gt; term()
</tt>
<h3><a name="map-2">map/2</a></h3>
-<tt>map(Fun, Dict) -> term()
+<tt>map(Fun, Dict) -&gt; term()
</tt>
<h3><a name="new-3">new/3</a></h3>
-<tt>new(Name, Candidates, Workers) -> term()
+<tt>new(Name, Candidates, Workers) -&gt; term()
</tt>
<h3><a name="store-3">store/3</a></h3>
-<tt>store(Key, Value, Dict) -> term()
+<tt>store(Key, Value, Dict) -&gt; term()
</tt>
<h3><a name="to_list-1">to_list/1</a></h3>
-<tt>to_list(Dict) -> term()
+<tt>to_list(Dict) -&gt; term()
</tt>
<h3><a name="update-3">update/3</a></h3>
-<tt>update(Key, Function, Dict) -> term()
+<tt>update(Key, Function, Dict) -&gt; term()
</tt>
<h3><a name="update-4">update/4</a></h3>
-<tt>update(Key, Function, Initial, Dict) -> term()
+<tt>update(Key, Function, Initial, Dict) -&gt; term()
</tt>
<h3><a name="update_counter-3">update_counter/3</a></h3>
-<tt>update_counter(Key, Incr, Dict) -> term()
+<tt>update_counter(Key, Incr, Dict) -&gt; term()
</tt>
</body>
</html>
@@ -6,26 +6,35 @@
</head>
<body bgcolor="white">
<h1>Module gen_leader</h1>
-Leader election behaviour.<ul><li><a href="#description">Description</a></li><li><a href="#types">Data Types</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul><p><b>Authors:</b> Ulf Wiger (<a href="mailto:ulf.wiger@ericsson.com"><tt>ulf.wiger@ericsson.com</tt></a>), Thomas Arts (<a href="mailto:thomas.arts@ituniv.se"><tt>thomas.arts@ituniv.se</tt></a>).</p>
-<h2><a name="description">Description</a></h2>Leader election behaviour.
- <p>This application implements a leader election behaviour modeled after
- gen_server. This behaviour intends to make it reasonably
- straightforward to implement a fully distributed server with
- master-slave semantics.</p>
- <p>The gen_leader behaviour supports nearly everything that gen_server
- does (some functions, such as multicall() and the internal timeout,
- have been removed), and adds a few callbacks and API functions to
- support leader election etc.</p>
- <p>Also included is an example program, a global dictionary, based
- on the modules gen_leader and dict. The callback implementing the
- global dictionary is called 'test_cb', for no particularly logical
- reason.</p>
+Leader election behavior.<ul><li><a href="#description">Description</a></li><li><a href="#types">Data Types</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul><p><b>Authors:</b> Hans Svensson (<a href="mailto:hanssv@cs.chalmers.se"><tt>hanssv@cs.chalmers.se</tt></a>), Thomas Arts (<a href="mailto:thomas.arts@ituniv.se"><tt>thomas.arts@ituniv.se</tt></a>), Ulf Wiger (<a href="mailto:ulf.wiger@ericsson.com"><tt>ulf.wiger@ericsson.com</tt></a>).</p>
+<h2><a name="description">Description</a></h2>Leader election behavior.
+ <p>This application implements a leader election behavior modeled after
+ gen_server. This behavior intends to make it reasonably
+ straightforward to implement a fully distributed server with
+ master-slave semantics.</p>
+ <p>The gen_leader behavior supports nearly everything that gen_server
+ does (some functions, such as multicall() and the internal timeout,
+ have been removed), and adds a few callbacks and API functions to
+ support leader election etc.</p>
+ <p>Also included is an example program, a global dictionary, based
+ on the modules gen_leader and dict. The callback implementing the
+ global dictionary is called 'test_cb', for no particularly logical
+ reason.</p>
+ <p><b>New version:</b> The internal leader election algorithm was faulty
+ and has been replaced with a new version based on a different leader
+ election algorithm. As a consequence of this the query functions
+ <tt>alive</tt> and <tt>down</tt> can no longer be provided.
+ The new algorithm also make use of an incarnation parameter, by
+ default written to disk in the function <tt>incarnation</tt>. This
+ implies that only one <tt>gen_leader</tt> per node is permitted, if
+ used in a diskless environment, <tt>incarnation</tt> must be adapted.
+ </p>
<h2><a name="types">Data Types</a></h2>
<h3><a name="type-callerRef">callerRef()</a></h3>
<p><tt>callerRef() = {pid(), reference()}</tt></p>
<p>See gen_server.
- </p>
+ </p>
<h3><a name="type-election">election()</a></h3>
<p><tt>election() = tuple()</tt></p>
@@ -44,15 +53,13 @@ <h3><a name="type-serverRef">serverRef()</a></h3>
<p>See gen_server.</p>
<h2><a name="index">Function Index</a></h2>
-<table width="100%" border="1"><tr><td valign="top"><a href="#alive-1">alive/1</a></td><td>Returns a list of live nodes (candidates and workers).</td></tr>
-<tr><td valign="top"><a href="#call-2">call/2</a></td><td>Equivalent to <code>gen_server:call/2</code>, but with a slightly
+<table width="100%" border="1"><tr><td valign="top"><a href="#call-2">call/2</a></td><td>Equivalent to <code>gen_server:call/2</code>, but with a slightly
different exit reason if something goes wrong.</td></tr>
<tr><td valign="top"><a href="#call-3">call/3</a></td><td>Equivalent to <code>gen_server:call/3</code>, but with a slightly
different exit reason if something goes wrong.</td></tr>
<tr><td valign="top"><a href="#candidates-1">candidates/1</a></td><td>Returns a list of known candidates.</td></tr>
<tr><td valign="top"><a href="#cast-2">cast/2</a></td><td><p>Equivalent to <tt>gen_server:cast / 2</tt>.</p>
</td></tr>
-<tr><td valign="top"><a href="#down-1">down/1</a></td><td>Returns a list of candidates currently not running.</td></tr>
<tr><td valign="top"><a href="#leader_call-2">leader_call/2</a></td><td>Makes a call (similar to <code>gen_server:call/2</code>) to the
leader.</td></tr>
<tr><td valign="top"><a href="#leader_call-3">leader_call/3</a></td><td>Makes a call (similar to <code>gen_server:call/3</code>) to the
@@ -68,43 +75,33 @@ <h2><a name="index">Function Index</a></h2>
<h2><a name="functions">Function Details</a></h2>
-<h3><a name="alive-1">alive/1</a></h3>
-<p><tt>alive(E::<a href="#type-election">election()</a>) -> [<a href="#type-node">node()</a>]</tt></p>
-<p>Returns a list of live nodes (candidates and workers).
- </p>
-
<h3><a name="call-2">call/2</a></h3>
-<p><tt>call(Name::<a href="#type-serverRef">serverRef()</a>, Request::Request) -> term()</tt></p>
+<p><tt>call(Name::<a href="#type-serverRef">serverRef()</a>, Request) -&gt; term()</tt></p>
<p>Equivalent to <code>gen_server:call/2</code>, but with a slightly
different exit reason if something goes wrong. This function calls
the <code>gen_leader</code> process exactly as if it were a gen_server
(which, for practical purposes, it is.)</p>
<h3><a name="call-3">call/3</a></h3>
-<p><tt>call(Name::<a href="#type-serverRef">serverRef()</a>, Request::Request, Timeout::integer()) -> Reply</tt>
+<p><tt>call(Name::<a href="#type-serverRef">serverRef()</a>, Request, Timeout::integer()) -&gt; Reply</tt>
<ul><li><tt>Reply = term()</tt></li></ul></p>
<p>Equivalent to <code>gen_server:call/3</code>, but with a slightly
different exit reason if something goes wrong. This function calls
the <code>gen_leader</code> process exactly as if it were a gen_server
(which, for practical purposes, it is.)</p>
<h3><a name="candidates-1">candidates/1</a></h3>
-<p><tt>candidates(E::<a href="#type-election">election()</a>) -> [<a href="#type-node">node()</a>]</tt></p>
+<p><tt>candidates(E::<a href="#type-election">election()</a>) -&gt; [<a href="#type-node">node()</a>]</tt></p>
<p>Returns a list of known candidates.
</p>
<h3><a name="cast-2">cast/2</a></h3>
-<tt>cast(Name, Request) -> term()
+<tt>cast(Name, Request) -&gt; term()
</tt><p>Equivalent to <tt>gen_server:cast / 2</tt>.</p>
-<h3><a name="down-1">down/1</a></h3>
-<p><tt>down(E::<a href="#type-election">election()</a>) -> [<a href="#type-node">node()</a>]</tt></p>
-<p>Returns a list of candidates currently not running.
- </p>
-
<h3><a name="leader_call-2">leader_call/2</a></h3>
-<p><tt>leader_call(Name::<a href="#type-name">name()</a>, Request::term()) -> Reply</tt>
+<p><tt>leader_call(Name::<a href="#type-name">name()</a>, Request::term()) -&gt; Reply</tt>
<ul><li><tt>Reply = term()</tt></li></ul></p>
<p>Makes a call (similar to <code>gen_server:call/2</code>) to the
leader. The call is forwarded via the local gen_leader instance, if
@@ -114,30 +111,30 @@ <h3><a name="leader_call-2">leader_call/2</a></h3>
same default timeout as e.g. <code>gen_server:call/2</code>.</p></p>
<h3><a name="leader_call-3">leader_call/3</a></h3>
-<p><tt>leader_call(Name::<a href="#type-name">name()</a>, Request::term(), Timeout::integer()) -> Reply</tt>
+<p><tt>leader_call(Name::<a href="#type-name">name()</a>, Request::term(), Timeout::integer()) -&gt; Reply</tt>
<ul><li><tt>Reply = term()</tt></li></ul></p>
<p>Makes a call (similar to <code>gen_server:call/3</code>) to the
leader. The call is forwarded via the local gen_leader instance, if
that one isn't actually the leader. The client will exit if the
leader dies while the request is outstanding.</p>
<h3><a name="leader_cast-2">leader_cast/2</a></h3>
-<p><tt>leader_cast(Name::<a href="#type-name">name()</a>, Msg::term()) -> ok</tt></p>
+<p><tt>leader_cast(Name::<a href="#type-name">name()</a>, Msg::term()) -&gt; ok</tt></p>
<p>Similar to <code>gen_server:cast/2</code> but will be forwarded to
the leader via the local gen_leader instance.</p>
<h3><a name="reply-2">reply/2</a></h3>
-<p><tt>reply(From::<a href="#type-callerRef">callerRef()</a>, Reply::term()) -> Void</tt></p>
+<p><tt>reply(From::<a href="#type-callerRef">callerRef()</a>, Reply::term()) -&gt; Void</tt></p>
<p>Equivalent to <tt>gen_server:reply / 2</tt>.</p>
<h3><a name="start-6">start/6</a></h3>
-<p><tt>start(Name::<a href="#type-node">node()</a>, CandidateNodes::[<a href="#type-node">node()</a>], Workers::[<a href="#type-node">node()</a>], Mod::atom(), Arg::Arg, Options::list()) -> {ok, pid()}</tt></p>
+<p><tt>start(Name::<a href="#type-node">node()</a>, CandidateNodes::[<a href="#type-node">node()</a>], Workers::[<a href="#type-node">node()</a>], Mod::atom(), Arg, Options::list()) -&gt; {ok, pid()}</tt></p>
<p>Starts a gen_leader process without linking to the parent.
</p>
<h3><a name="start_link-6">start_link/6</a></h3>
-<p><tt>start_link(Name::atom(), CandidateNodes::[atom()], Workers::[atom()], Mod::atom(), Arg::Arg, Options::list()) -> {ok, pid()}</tt></p>
+<p><tt>start_link(Name::atom(), CandidateNodes::[atom()], Workers::[atom()], Mod::atom(), Arg, Options::list()) -&gt; {ok, pid()}</tt></p>
<p>Starts a gen_leader process.
<table>
<tr><td>Name</td><td>The locally registered name of the process</td></tr>
@@ -155,7 +152,7 @@ <h3><a name="start_link-6">start_link/6</a></h3>
can be added at runtime.</p></p>
<h3><a name="workers-1">workers/1</a></h3>
-<p><tt>workers(E::<a href="#type-election">election()</a>) -> [<a href="#type-node">node()</a>]</tt></p>
+<p><tt>workers(E::<a href="#type-election">election()</a>) -&gt; [<a href="#type-node">node()</a>]</tt></p>
<p>Returns a list of known workers.
</p>
</body>
@@ -1,16 +1,16 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
-<title>The gen_leader application</title>
+<title>Welcome to gen_leader</title>
</head>
<frameset cols="20%,80%">
<frame src="modules-frame.html" name="modulesFrame" title="">
<frame src="overview-summary.html" name="overviewFrame" title="">
<noframes>
-<h2>Yo, man!</h2>
-<p>Your browser does not dig frames, man!
-<br>You should be going to the <a href="overview-summary.html">non-frame version</a> instead.
+<h2>This page uses frames</h2>
+<p>Your browser does not accept frames.
+<br>You should go to the <a href="overview-summary.html">non-frame version</a> instead.
</p>
</noframes>
</frameset>
@@ -1,7 +1,7 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
-<title>The gen_leader application</title>
+<title>Welcome to gen_leader</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>
<body bgcolor="white">
Oops, something went wrong.

0 comments on commit abaf7ee

Please sign in to comment.