Add first basic round of EDoc documentation, 'make edoc' target
This commit is contained in:
parent
0e38eddaa9
commit
ad872e23ca
38 changed files with 2232 additions and 26 deletions
8
Makefile
8
Makefile
|
@ -3,7 +3,7 @@ ifeq ($(REBAR_BIN),)
|
|||
REBAR_BIN = ./rebar
|
||||
endif
|
||||
|
||||
.PHONY: rel deps package pkgclean
|
||||
.PHONY: rel deps package pkgclean edoc
|
||||
|
||||
all: deps compile
|
||||
|
||||
|
@ -21,6 +21,12 @@ test: deps compile eunit
|
|||
eunit:
|
||||
$(REBAR_BIN) -v skip_deps=true eunit
|
||||
|
||||
edoc: edoc-clean
|
||||
$(REBAR_BIN) skip_deps=true doc
|
||||
|
||||
edoc-clean:
|
||||
rm -f edoc/*.png edoc/*.html edoc/*.css edoc/edoc-info
|
||||
|
||||
pulse: compile
|
||||
env USE_PULSE=1 $(REBAR_BIN) skip_deps=true clean compile
|
||||
env USE_PULSE=1 $(REBAR_BIN) skip_deps=true -D PULSE eunit
|
||||
|
|
170
doc/overview.edoc
Normal file
170
doc/overview.edoc
Normal file
|
@ -0,0 +1,170 @@
|
|||
|
||||
@title Machi: a small village of replicated files
|
||||
|
||||
@doc
|
||||
|
||||
== About This EDoc Documentation ==
|
||||
|
||||
This EDoc-style documentation will concern itself only with Erlang
|
||||
function APIs and function & data types. Higher-level design and
|
||||
commentary will remain outside of the Erlang EDoc system; please see
|
||||
the "Pointers to Other Machi Documentation" section below for more
|
||||
details.
|
||||
|
||||
Readers should beware that this documentation may be out-of-sync with
|
||||
the source code. When in doubt, use the `make edoc' command to
|
||||
regenerate all HTML pages.
|
||||
|
||||
It is the developer's responsibility to re-generate the documentation
|
||||
periodically and commit it to the Git repo.
|
||||
|
||||
== Machi Code Overview ==
|
||||
|
||||
=== Chain Manager ===
|
||||
|
||||
The Chain Manager is responsible for managing the state of Machi's
|
||||
"Chain Replication" state. This role is roughly analogous to the
|
||||
"Riak Core" application inside of Riak, which takes care of
|
||||
coordinating replica placement and replica repair.
|
||||
|
||||
For each primitive data server in the cluster, a Machi FLU, there is a
|
||||
Chain Manager process that manages its FLU's role within the Machi
|
||||
cluster's Chain Replication scheme. Each Chain Manager process
|
||||
executes locally and independently to manage the distributed state of
|
||||
a single Machi Chain Replication chain.
|
||||
|
||||
<ul>
|
||||
|
||||
<li> To contrast with Riak Core ... Riak Core's claimant process is
|
||||
solely responsible for managing certain critical aspects of
|
||||
Riak Core distributed state. Machi's Chain Manager process
|
||||
performs similar tasks as Riak Core's claimant. However, Machi
|
||||
has several active Chain Manager processes, one per FLU server,
|
||||
instead of a single active process like Core's claimant. Each
|
||||
Chain Manager process acts independently; each is constrained
|
||||
so that it will reach consensus via independent computation
|
||||
& action.
|
||||
|
||||
Full discussion of this distributed consensus is outside the
|
||||
scope of this document; see the "Pointers to Other Machi
|
||||
Documentation" section below for more information.
|
||||
</li>
|
||||
<li> Machi differs from a Riak Core application because Machi's
|
||||
replica placement policy is simply, "All Machi servers store
|
||||
replicas of all Machi files".
|
||||
Machi is intended to be a primitive building block for creating larger
|
||||
cluster-of-clusters where files are
|
||||
distributed/fragmented/sharded across a large pool of
|
||||
independent Machi clusters.
|
||||
</li>
|
||||
<li> See
|
||||
[https://www.usenix.org/legacy/events/osdi04/tech/renesse.html]
|
||||
for a copy of the paper, "Chain Replication for Supporting High
|
||||
Throughput and Availability" by Robbert van Renesse and Fred
|
||||
B. Schneider.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
=== FLU ===
|
||||
|
||||
The FLU is the basic storage server for Machi.
|
||||
|
||||
<ul>
|
||||
<li> The name FLU is taken from "flash storage unit" from the paper
|
||||
"CORFU: A Shared Log Design for Flash Clusters" by
|
||||
Balakrishnan, Malkhi, Prabhakaran, and Wobber. See
|
||||
[https://www.usenix.org/conference/nsdi12/technical-sessions/presentation/balakrishnan]
|
||||
</li>
|
||||
<li> In CORFU, the sequencer step is a prerequisite step that is
|
||||
performed by a separate component, the Sequencer.
|
||||
In Machi, the `append_chunk()' protocol message has
|
||||
an implicit "sequencer" operation applied by the "head" of the
|
||||
Machi Chain Replication chain. If a client wishes to write
|
||||
data that has already been assigned a sequencer position, then
|
||||
the `write_chunk()' API function is used.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
For each FLU, there are three independent tasks that are implemented
|
||||
using three different Erlang processes:
|
||||
|
||||
<ul>
|
||||
<li> A FLU server, implemented primarily by `machi_flu.erl'.
|
||||
</li>
|
||||
<li> A projection store server, implemented primarily by
|
||||
`machi_projection_store.erl'.
|
||||
</li>
|
||||
<li> A chain state manager server, implemented primarily by
|
||||
`machi_chain_manager1.erl'.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
From the perspective of failure detection, it is very convenient that
|
||||
all three FLU-related services (file server, sequencer server, and
|
||||
projection server) are accessed using the same single TCP port.
|
||||
|
||||
=== Projection (data structure) ===
|
||||
|
||||
The projection is a data structure that specifies the current state
|
||||
of the Machi cluster: all FLUs, which FLUS are considered
|
||||
up/running or down/crashed/stopped, which FLUs are actively
|
||||
participants in the Chain Replication protocol, and which FLUs are
|
||||
under "repair" (i.e., having their data resyncronized when
|
||||
newly-added to a cluster or when restarting after a crash).
|
||||
|
||||
=== Projection Store (server) ===
|
||||
|
||||
The projection store is a storage service that is implemented by an
|
||||
Erlang/OTP `gen_server' process that is associated with each
|
||||
FLU. Conceptually, the projection store is an array of
|
||||
write-once registers. For each projection store register, the
|
||||
key is a 2-tuple of an epoch number (`non_neg_integer()' type)
|
||||
and a projection type (`public' or `private' type); the value is
|
||||
a projection data structure (`projection_v1()' type).
|
||||
|
||||
=== Client and Proxy Client ===
|
||||
|
||||
Machi is intentionally avoiding using distributed Erlang for Machi's
|
||||
communication. This design decision makes Erlang-side code more
|
||||
difficult & complex but allows us the freedom of implementing
|
||||
parts of Machi in other languages without major
|
||||
protocol&API&glue code changes later in the product's
|
||||
lifetime.
|
||||
|
||||
There are two layers of interface for Machi clients.
|
||||
|
||||
<ul>
|
||||
<li> The `machi_flu1_client' module implements an API that uses a
|
||||
TCP socket directly.
|
||||
</li>
|
||||
<li> The `machi_proxy_flu1_client' module implements an API that
|
||||
uses a local, long-lived `gen_server' process as a proxy for
|
||||
the remote, perhaps disconnected-or-crashed Machi FLU server.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
The types for both modules ought to be the same. However, due to
|
||||
rapid code churn, some differences might exist. Any major difference
|
||||
is (almost by definition) a bug: please open a GitHub issue to request
|
||||
a correction.
|
||||
|
||||
== TODO notes ==
|
||||
|
||||
Any use of the string "TODO" in upper/lower/mixed case, anywhere in
|
||||
the code, is a reminder signal of unfinished work.
|
||||
|
||||
== Pointers to Other Machi Documentation ==
|
||||
|
||||
<ul>
|
||||
<li> If you are viewing this document locally, please look in the
|
||||
`../doc/' directory,
|
||||
</li>
|
||||
<li> If you are viewing this document via the Web, please find the
|
||||
documentation via this link:
|
||||
[http://github.com/basho/machi/tree/master/doc/]
|
||||
Please be aware that this link points to the `master' branch
|
||||
of the Machi source repository and therefore may be
|
||||
out-of-sync with non-`master' branch code.
|
||||
</li>
|
||||
|
||||
</ul>
|
1
edoc/.gitignore
vendored
Normal file
1
edoc/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
tmp.*
|
7
edoc/edoc-info
Normal file
7
edoc/edoc-info
Normal file
|
@ -0,0 +1,7 @@
|
|||
%% encoding: UTF-8
|
||||
{application,machi}.
|
||||
{packages,[]}.
|
||||
{modules,[machi_admin_util,machi_app,machi_chain_manager1,machi_chash,
|
||||
machi_flu1,machi_flu1_client,machi_flu_sup,machi_projection,
|
||||
machi_projection_store,machi_proxy_flu1_client,machi_sequencer,
|
||||
machi_sup,machi_util]}.
|
BIN
edoc/erlang.png
Normal file
BIN
edoc/erlang.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
17
edoc/index.html
Normal file
17
edoc/index.html
Normal file
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>The machi application</title>
|
||||
</head>
|
||||
<frameset cols="20%,80%">
|
||||
<frame src="modules-frame.html" name="modulesFrame" title="">
|
||||
|
||||
<frame src="overview-summary.html" name="overviewFrame" title="">
|
||||
<noframes>
|
||||
<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>
|
||||
</html>
|
60
edoc/machi_admin_util.html
Normal file
60
edoc/machi_admin_util.html
Normal file
|
@ -0,0 +1,60 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Module machi_admin_util</title>
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<hr>
|
||||
|
||||
<h1>Module machi_admin_util</h1>
|
||||
<ul class="index"><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>Machi chain replication administration utilities.
|
||||
|
||||
|
||||
<h2><a name="description">Description</a></h2>Machi chain replication administration utilities.
|
||||
<h2><a name="types">Data Types</a></h2>
|
||||
|
||||
<h3 class="typedecl"><a name="type-inet_host">inet_host()</a></h3>
|
||||
<p><tt>inet_host() = <a href="inet.html#type-ip_address">inet:ip_address()</a> | <a href="inet.html#type-hostname">inet:hostname()</a></tt></p>
|
||||
|
||||
|
||||
<h3 class="typedecl"><a name="type-inet_port">inet_port()</a></h3>
|
||||
<p><tt>inet_port() = <a href="inet.html#type-port_number">inet:port_number()</a></tt></p>
|
||||
|
||||
|
||||
<h2><a name="index">Function Index</a></h2>
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#verify_file_checksums_local-3">verify_file_checksums_local/3</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#verify_file_checksums_local-4">verify_file_checksums_local/4</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#verify_file_checksums_remote-3">verify_file_checksums_remote/3</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#verify_file_checksums_remote-4">verify_file_checksums_remote/4</a></td><td></td></tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="functions">Function Details</a></h2>
|
||||
|
||||
<h3 class="function"><a name="verify_file_checksums_local-3">verify_file_checksums_local/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>verify_file_checksums_local(Sock1::port(), EpochID::<a href="machi_flu1_client.html#type-epoch_id">machi_flu1_client:epoch_id()</a>, Path::binary() | list()) -> {ok, [tuple()]} | {error, term()}</tt><br></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="verify_file_checksums_local-4">verify_file_checksums_local/4</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>verify_file_checksums_local(Host::<a href="#type-inet_host">inet_host()</a>, TcpPort::<a href="#type-inet_port">inet_port()</a>, EpochID::<a href="machi_flu1_client.html#type-epoch_id">machi_flu1_client:epoch_id()</a>, Path::binary() | list()) -> {ok, [tuple()]} | {error, term()}</tt><br></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="verify_file_checksums_remote-3">verify_file_checksums_remote/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>verify_file_checksums_remote(Sock1::port(), EpochID::<a href="machi_flu1_client.html#type-epoch_id">machi_flu1_client:epoch_id()</a>, File::binary() | list()) -> {ok, [tuple()]} | {error, term()}</tt><br></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="verify_file_checksums_remote-4">verify_file_checksums_remote/4</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>verify_file_checksums_remote(Host::<a href="#type-inet_host">inet_host()</a>, TcpPort::<a href="#type-inet_port">inet_port()</a>, EpochID::<a href="machi_flu1_client.html#type-epoch_id">machi_flu1_client:epoch_id()</a>, File::binary() | list()) -> {ok, [tuple()]} | {error, term()}</tt><br></p>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<p><i>Generated by EDoc, Apr 8 2015, 17:31:11.</i></p>
|
||||
</body>
|
||||
</html>
|
39
edoc/machi_app.html
Normal file
39
edoc/machi_app.html
Normal file
|
@ -0,0 +1,39 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Module machi_app</title>
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<hr>
|
||||
|
||||
<h1>Module machi_app</h1>
|
||||
<ul class="index"><li><a href="#description">Description</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>Top-level supervisor for the Machi application.
|
||||
|
||||
<p><b>Behaviours:</b> <a href="application.html"><tt>application</tt></a>.</p>
|
||||
|
||||
<h2><a name="description">Description</a></h2>Top-level supervisor for the Machi application.
|
||||
<h2><a name="index">Function Index</a></h2>
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#start-2">start/2</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#stop-1">stop/1</a></td><td></td></tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="functions">Function Details</a></h2>
|
||||
|
||||
<h3 class="function"><a name="start-2">start/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>start(StartType, StartArgs) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="stop-1">stop/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>stop(State) -> any()</tt></p>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<p><i>Generated by EDoc, Apr 8 2015, 17:31:11.</i></p>
|
||||
</body>
|
||||
</html>
|
155
edoc/machi_chain_manager1.html
Normal file
155
edoc/machi_chain_manager1.html
Normal file
|
@ -0,0 +1,155 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Module machi_chain_manager1</title>
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<hr>
|
||||
|
||||
<h1>Module machi_chain_manager1</h1>
|
||||
<ul class="index"><li><a href="#description">Description</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>The Machi chain manager, Guardian of all things related to
|
||||
Chain Replication state, status, and data replica safety.
|
||||
|
||||
<p><b>Behaviours:</b> <a href="gen_server.html"><tt>gen_server</tt></a>.</p>
|
||||
|
||||
<h2><a name="description">Description</a></h2><p>The Machi chain manager, Guardian of all things related to
|
||||
Chain Replication state, status, and data replica safety.</p>
|
||||
|
||||
<p>The Chain Manager is responsible for managing the state of Machi's
|
||||
"Chain Replication" state. This role is roughly analogous to the
|
||||
"Riak Core" application inside of Riak, which takes care of
|
||||
coordinating replica placement and replica repair.</p>
|
||||
|
||||
<p>For each primitive data server in the cluster, a Machi FLU, there
|
||||
is a Chain Manager process that manages its FLU's role within the
|
||||
Machi cluster's Chain Replication scheme. Each Chain Manager
|
||||
process executes locally and independently to manage the
|
||||
distributed state of a single Machi Chain Replication chain.</p>
|
||||
|
||||
Machi's Chain Manager process performs similar tasks as Riak Core's
|
||||
claimant. However, Machi has several active Chain Manager
|
||||
processes, one per FLU server, instead of a single active process
|
||||
like Core's claimant. Each Chain Manager process acts
|
||||
independently; each is constrained so that it will reach consensus
|
||||
via independent computation & action.
|
||||
<h2><a name="index">Function Index</a></h2>
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#code_change-3">code_change/3</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#get_all_hosed-1">get_all_hosed/1</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#handle_call-3">handle_call/3</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#handle_cast-2">handle_cast/2</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#handle_info-2">handle_info/2</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#init-1">init/1</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#make_projection_summary-1">make_projection_summary/1</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#ping-1">ping/1</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#projection_transitions_are_sane-2">projection_transitions_are_sane/2</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#start_link-3">start_link/3</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#start_link-4">start_link/4</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#stop-1">stop/1</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#terminate-2">terminate/2</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#test_calc_projection-2">test_calc_projection/2</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#test_calc_proposed_projection-1">test_calc_proposed_projection/1</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#test_react_to_env-1">test_react_to_env/1</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#test_read_latest_public_projection-2">test_read_latest_public_projection/2</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#test_write_proposed_projection-1">test_write_proposed_projection/1</a></td><td></td></tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="functions">Function Details</a></h2>
|
||||
|
||||
<h3 class="function"><a name="code_change-3">code_change/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>code_change(OldVsn, S, Extra) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="get_all_hosed-1">get_all_hosed/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>get_all_hosed(P) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="handle_call-3">handle_call/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>handle_call(Call, From, Ch_mgr) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="handle_cast-2">handle_cast/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>handle_cast(Cast, Ch_mgr) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="handle_info-2">handle_info/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>handle_info(Msg, S) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="init-1">init/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>init(X1) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="make_projection_summary-1">make_projection_summary/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>make_projection_summary(Projection_v1) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="ping-1">ping/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>ping(Pid) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="projection_transitions_are_sane-2">projection_transitions_are_sane/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>projection_transitions_are_sane(Ps, RelativeToServer) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="start_link-3">start_link/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>start_link(MyName, All_list, MyFLUPid) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="start_link-4">start_link/4</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>start_link(MyName, All_list, MyFLUPid, MgrOpts) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="stop-1">stop/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>stop(Pid) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="terminate-2">terminate/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>terminate(Reason, S) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="test_calc_projection-2">test_calc_projection/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>test_calc_projection(Pid, KeepRunenvP) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="test_calc_proposed_projection-1">test_calc_proposed_projection/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>test_calc_proposed_projection(Pid) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="test_react_to_env-1">test_react_to_env/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>test_react_to_env(Pid) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="test_read_latest_public_projection-2">test_read_latest_public_projection/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>test_read_latest_public_projection(Pid, ReadRepairP) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="test_write_proposed_projection-1">test_write_proposed_projection/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>test_write_proposed_projection(Pid) -> any()</tt></p>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<p><i>Generated by EDoc, Apr 8 2015, 17:31:11.</i></p>
|
||||
</body>
|
||||
</html>
|
171
edoc/machi_chash.html
Normal file
171
edoc/machi_chash.html
Normal file
|
@ -0,0 +1,171 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Module machi_chash</title>
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<hr>
|
||||
|
||||
<h1>Module machi_chash</h1>
|
||||
<ul class="index"><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>Consistent hashing library.
|
||||
|
||||
|
||||
<h2><a name="description">Description</a></h2><p>Consistent hashing library. Also known as "random slicing".</p>
|
||||
|
||||
This code was originally from the Hibari DB source code at
|
||||
<a href="https://github.com/hibari" target="_top"><tt>https://github.com/hibari</tt></a>
|
||||
<h2><a name="types">Data Types</a></h2>
|
||||
|
||||
<h3 class="typedecl"><a name="type-float_map">float_map()</a></h3>
|
||||
<p><tt>float_map() = [{<a href="#type-owner_name">owner_name()</a>, float()}]</tt></p>
|
||||
<p> A float map subdivides the unit interval, starting at 0.0, to
|
||||
partitions that are assigned to various owners. The sum of all
|
||||
floats must be exactly 1.0 (or close enough for floating point
|
||||
purposes).</p>
|
||||
|
||||
<h3 class="typedecl"><a name="type-float_tree">float_tree()</a></h3>
|
||||
<p><b>abstract datatype</b>: <tt>float_tree()</tt></p>
|
||||
<p> We can't use gb_trees:tree() because 'nil' (the empty tree) is
|
||||
never valid in our case. But teaching Dialyzer that is difficult.</p>
|
||||
|
||||
<h3 class="typedecl"><a name="type-nextfloat_list">nextfloat_list()</a></h3>
|
||||
<p><tt>nextfloat_list() = [{float(), <a href="#type-brick">brick()</a>}]</tt></p>
|
||||
<p>A nextfloat_list
|
||||
differs from a float_map in two respects: 1) nextfloat_list contains
|
||||
tuples with the brick name in 2nd position, 2) the float() at each
|
||||
position I_n > I_m, for all n, m such that n > m.
|
||||
For example, a nextfloat_list of the float_map example above,
|
||||
[{0.25, {br1, nd1}}, {0.75, {br2, nd1}}, {1.0, {br3, nd1}].</p>
|
||||
|
||||
<h3 class="typedecl"><a name="type-owner_int_range">owner_int_range()</a></h3>
|
||||
<p><tt>owner_int_range() = {<a href="#type-owner_name">owner_name()</a>, non_neg_integer(), non_neg_integer()}</tt></p>
|
||||
<p> Used when "prettying" a float map.</p>
|
||||
|
||||
<h3 class="typedecl"><a name="type-owner_name">owner_name()</a></h3>
|
||||
<p><tt>owner_name() = term()</tt></p>
|
||||
<p> Owner for a range on the unit interval. We are agnostic about its
|
||||
type.</p>
|
||||
|
||||
<h3 class="typedecl"><a name="type-owner_weight">owner_weight()</a></h3>
|
||||
<p><tt>owner_weight() = {<a href="#type-owner_name">owner_name()</a>, <a href="#type-weight">weight()</a>}</tt></p>
|
||||
|
||||
|
||||
<h3 class="typedecl"><a name="type-owner_weight_list">owner_weight_list()</a></h3>
|
||||
<p><tt>owner_weight_list() = [<a href="#type-owner_weight">owner_weight()</a>]</tt></p>
|
||||
<p> A owner_weight_list is a definition of brick assignments over the
|
||||
unit interval [0.0, 1.0]. The sum of all floats must be 1.0. For
|
||||
example, [{{br1,nd1}, 0.25}, {{br2,nd1}, 0.5}, {{br3,nd1}, 0.25}].</p>
|
||||
|
||||
<h3 class="typedecl"><a name="type-weight">weight()</a></h3>
|
||||
<p><tt>weight() = non_neg_integer()</tt></p>
|
||||
<p> For this library, a weight is an integer which specifies the
|
||||
capacity of a "owner" relative to other owners. For example, if
|
||||
owner A with a weight of 10, and if owner B has a weight of 20,
|
||||
then B will be assigned twice as much of the unit interval as A.</p>
|
||||
|
||||
<h2><a name="index">Function Index</a></h2>
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#hash_binary_via_float_map-2">hash_binary_via_float_map/2</a></td><td>Query a float map with a binary (inefficient).</td></tr>
|
||||
<tr><td valign="top"><a href="#hash_binary_via_float_tree-2">hash_binary_via_float_tree/2</a></td><td>Query a float tree with a binary.</td></tr>
|
||||
<tr><td valign="top"><a href="#make_demo_map1-0">make_demo_map1/0</a></td><td>Create a sample float map.</td></tr>
|
||||
<tr><td valign="top"><a href="#make_demo_map2-0">make_demo_map2/0</a></td><td>Create a sample float map.</td></tr>
|
||||
<tr><td valign="top"><a href="#make_float_map-1">make_float_map/1</a></td><td>Create a float map, based on a basic owner weight list.</td></tr>
|
||||
<tr><td valign="top"><a href="#make_float_map-2">make_float_map/2</a></td><td>Create a float map, based on an older float map and a new weight
|
||||
list.</td></tr>
|
||||
<tr><td valign="top"><a href="#make_tree-1">make_tree/1</a></td><td>Create a float tree, which is the rapid lookup data structure
|
||||
for consistent hash queries.</td></tr>
|
||||
<tr><td valign="top"><a href="#pretty_with_integers-2">pretty_with_integers/2</a></td><td>Make a pretty/human-friendly version of a float map that describes
|
||||
integer ranges between 1 and <code>Scale</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#pretty_with_integers-3">pretty_with_integers/3</a></td><td>Make a pretty/human-friendly version of a float map (based
|
||||
upon a float map created from <code>OldWeights</code> and <code>NewWeights</code>) that
|
||||
describes integer ranges between 1 and <code>Scale</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#query_tree-2">query_tree/2</a></td><td>Low-level function for querying a float tree: the (floating
|
||||
point) point within the unit interval.</td></tr>
|
||||
<tr><td valign="top"><a href="#sum_map_weights-1">sum_map_weights/1</a></td><td>Create a human-friendly summary of a float map.</td></tr>
|
||||
<tr><td valign="top"><a href="#zzz_usage_details-0">zzz_usage_details/0</a></td><td>Various usage examples, see source code below this function
|
||||
for full details.</td></tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="functions">Function Details</a></h2>
|
||||
|
||||
<h3 class="function"><a name="hash_binary_via_float_map-2">hash_binary_via_float_map/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>hash_binary_via_float_map(Key::binary(), Map::<a href="#type-float_map">float_map()</a>) -> {float(), <a href="#type-owner_name">owner_name()</a>}</tt><br></p>
|
||||
</div><p>Query a float map with a binary (inefficient).</p>
|
||||
|
||||
<h3 class="function"><a name="hash_binary_via_float_tree-2">hash_binary_via_float_tree/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>hash_binary_via_float_tree(Key::binary(), Tree::<a href="#type-float_tree">float_tree()</a>) -> {float(), <a href="#type-owner_name">owner_name()</a>}</tt><br></p>
|
||||
</div><p>Query a float tree with a binary.</p>
|
||||
|
||||
<h3 class="function"><a name="make_demo_map1-0">make_demo_map1/0</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>make_demo_map1() -> <a href="#type-float_map">float_map()</a></tt><br></p>
|
||||
</div><p>Create a sample float map.</p>
|
||||
|
||||
<h3 class="function"><a name="make_demo_map2-0">make_demo_map2/0</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>make_demo_map2() -> <a href="#type-float_map">float_map()</a></tt><br></p>
|
||||
</div><p>Create a sample float map.</p>
|
||||
|
||||
<h3 class="function"><a name="make_float_map-1">make_float_map/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>make_float_map(NewOwnerWeights::<a href="#type-owner_weight_list">owner_weight_list()</a>) -> <a href="#type-float_map">float_map()</a></tt><br></p>
|
||||
</div><p>Create a float map, based on a basic owner weight list.</p>
|
||||
|
||||
<h3 class="function"><a name="make_float_map-2">make_float_map/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>make_float_map(OldFloatMap::<a href="#type-float_map">float_map()</a>, NewOwnerWeights::<a href="#type-owner_weight_list">owner_weight_list()</a>) -> <a href="#type-float_map">float_map()</a></tt><br></p>
|
||||
</div><p><p>Create a float map, based on an older float map and a new weight
|
||||
list.</p>
|
||||
|
||||
The weights in the new weight list may be different than (or the
|
||||
same as) whatever weights were used to make the older float map.</p>
|
||||
|
||||
<h3 class="function"><a name="make_tree-1">make_tree/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>make_tree(Map::<a href="#type-float_map">float_map()</a>) -> <a href="#type-float_tree">float_tree()</a></tt><br></p>
|
||||
</div><p>Create a float tree, which is the rapid lookup data structure
|
||||
for consistent hash queries.</p>
|
||||
|
||||
<h3 class="function"><a name="pretty_with_integers-2">pretty_with_integers/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>pretty_with_integers(Map::<a href="#type-float_map">float_map()</a>, Scale::integer()) -> [<a href="#type-owner_int_range">owner_int_range()</a>]</tt><br></p>
|
||||
</div><p>Make a pretty/human-friendly version of a float map that describes
|
||||
integer ranges between 1 and <code>Scale</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="pretty_with_integers-3">pretty_with_integers/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>pretty_with_integers(OldWeights::<a href="#type-owner_weight_list">owner_weight_list()</a>, NewWeights::<a href="#type-owner_weight_list">owner_weight_list()</a>, Scale::integer()) -> [<a href="#type-owner_int_range">owner_int_range()</a>]</tt><br></p>
|
||||
</div><p>Make a pretty/human-friendly version of a float map (based
|
||||
upon a float map created from <code>OldWeights</code> and <code>NewWeights</code>) that
|
||||
describes integer ranges between 1 and <code>Scale</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="query_tree-2">query_tree/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>query_tree(Val::float(), Tree::<a href="#type-float_tree">float_tree()</a>) -> {float(), <a href="#type-owner_name">owner_name()</a>}</tt><br></p>
|
||||
</div><p>Low-level function for querying a float tree: the (floating
|
||||
point) point within the unit interval.</p>
|
||||
|
||||
<h3 class="function"><a name="sum_map_weights-1">sum_map_weights/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>sum_map_weights(Map::<a href="#type-float_map">float_map()</a>) -> {{per_owner, <a href="#type-float_map">float_map()</a>}, {weight_sum, float()}}</tt><br></p>
|
||||
</div><p><p>Create a human-friendly summary of a float map.</p>
|
||||
|
||||
The two parts of the summary are: a per-owner total of the unit
|
||||
interval range(s) owned by each owner, and a total sum of all
|
||||
per-owner ranges (which should be 1.0 but is not enforced).</p>
|
||||
|
||||
<h3 class="function"><a name="zzz_usage_details-0">zzz_usage_details/0</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>zzz_usage_details() -> any()</tt></p>
|
||||
</div><p>Various usage examples, see source code below this function
|
||||
for full details.</p>
|
||||
<hr>
|
||||
|
||||
<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<p><i>Generated by EDoc, Apr 8 2015, 17:31:11.</i></p>
|
||||
</body>
|
||||
</html>
|
63
edoc/machi_flu1.html
Normal file
63
edoc/machi_flu1.html
Normal file
|
@ -0,0 +1,63 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Module machi_flu1</title>
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<hr>
|
||||
|
||||
<h1>Module machi_flu1</h1>
|
||||
<ul class="index"><li><a href="#description">Description</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>The Machi FLU file server + file location sequencer.
|
||||
|
||||
|
||||
<h2><a name="description">Description</a></h2><p>The Machi FLU file server + file location sequencer.</p>
|
||||
|
||||
<p>This module implements only the Machi FLU file server and its
|
||||
implicit sequencer.
|
||||
Please see the EDoc "Overview" for details about the FLU as a
|
||||
primitive file server process vs. the larger Machi design of a FLU
|
||||
as a sequencer + file server + chain manager group of processes.</p>
|
||||
|
||||
<p>For the moment, this module also implements a rudimentary TCP-based
|
||||
protocol as the sole supported access method to the server,
|
||||
sequencer, and projection store. Conceptually, those three
|
||||
services are independent and ought to have their own protocols. As
|
||||
a practical matter, there is no need for wire protocol
|
||||
compatibility. Furthermore, from the perspective of failure
|
||||
detection, it is very convenient that all three FLU-related
|
||||
services are accessed using the same single TCP port.</p>
|
||||
|
||||
<p>The FLU is named after the CORFU server "FLU" or "FLash Unit" server.</p>
|
||||
|
||||
TODO There is one major missing feature in this FLU implementation:
|
||||
there is no "write-once" enforcement for any position in a Machi
|
||||
file. At the moment, we rely on correct behavior of the client
|
||||
& the sequencer to avoid overwriting data. In the Real World,
|
||||
however, all Machi file data is supposed to be exactly write-once
|
||||
to avoid problems with bugs, wire protocol corruption, malicious
|
||||
clients, etc.
|
||||
<h2><a name="index">Function Index</a></h2>
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#start_link-1">start_link/1</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#stop-1">stop/1</a></td><td></td></tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="functions">Function Details</a></h2>
|
||||
|
||||
<h3 class="function"><a name="start_link-1">start_link/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>start_link(Rest) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="stop-1">stop/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>stop(Pid) -> any()</tt></p>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<p><i>Generated by EDoc, Apr 8 2015, 17:31:11.</i></p>
|
||||
</body>
|
||||
</html>
|
278
edoc/machi_flu1_client.html
Normal file
278
edoc/machi_flu1_client.html
Normal file
|
@ -0,0 +1,278 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Module machi_flu1_client</title>
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<hr>
|
||||
|
||||
<h1>Module machi_flu1_client</h1>
|
||||
<ul class="index"><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>Erlang API for the Machi FLU TCP protocol version 1.
|
||||
|
||||
|
||||
<h2><a name="description">Description</a></h2>Erlang API for the Machi FLU TCP protocol version 1.
|
||||
<h2><a name="types">Data Types</a></h2>
|
||||
|
||||
<h3 class="typedecl"><a name="type-chunk">chunk()</a></h3>
|
||||
<p><tt>chunk() = binary() | iolist()</tt></p>
|
||||
<p> client can use either</p>
|
||||
|
||||
<h3 class="typedecl"><a name="type-chunk_csum">chunk_csum()</a></h3>
|
||||
<p><tt>chunk_csum() = {<a href="#type-file_offset">file_offset()</a>, <a href="#type-chunk_size">chunk_size()</a>, binary()}</tt></p>
|
||||
|
||||
|
||||
<h3 class="typedecl"><a name="type-chunk_pos">chunk_pos()</a></h3>
|
||||
<p><tt>chunk_pos() = {<a href="#type-file_offset">file_offset()</a>, <a href="#type-chunk_size">chunk_size()</a>, <a href="#type-file_name_s">file_name_s()</a>}</tt></p>
|
||||
|
||||
|
||||
<h3 class="typedecl"><a name="type-chunk_s">chunk_s()</a></h3>
|
||||
<p><tt>chunk_s() = binary()</tt></p>
|
||||
<p> server always uses binary()</p>
|
||||
|
||||
<h3 class="typedecl"><a name="type-chunk_size">chunk_size()</a></h3>
|
||||
<p><tt>chunk_size() = non_neg_integer()</tt></p>
|
||||
|
||||
|
||||
<h3 class="typedecl"><a name="type-epoch_csum">epoch_csum()</a></h3>
|
||||
<p><tt>epoch_csum() = binary()</tt></p>
|
||||
|
||||
|
||||
<h3 class="typedecl"><a name="type-epoch_id">epoch_id()</a></h3>
|
||||
<p><tt>epoch_id() = {<a href="#type-epoch_num">epoch_num()</a>, <a href="#type-epoch_csum">epoch_csum()</a>}</tt></p>
|
||||
|
||||
|
||||
<h3 class="typedecl"><a name="type-epoch_num">epoch_num()</a></h3>
|
||||
<p><tt>epoch_num() = -1 | non_neg_integer()</tt></p>
|
||||
|
||||
|
||||
<h3 class="typedecl"><a name="type-file_info">file_info()</a></h3>
|
||||
<p><tt>file_info() = {<a href="#type-file_size">file_size()</a>, <a href="#type-file_name_s">file_name_s()</a>}</tt></p>
|
||||
|
||||
|
||||
<h3 class="typedecl"><a name="type-file_name">file_name()</a></h3>
|
||||
<p><tt>file_name() = binary() | list()</tt></p>
|
||||
|
||||
|
||||
<h3 class="typedecl"><a name="type-file_name_s">file_name_s()</a></h3>
|
||||
<p><tt>file_name_s() = binary()</tt></p>
|
||||
<p> server reply</p>
|
||||
|
||||
<h3 class="typedecl"><a name="type-file_offset">file_offset()</a></h3>
|
||||
<p><tt>file_offset() = non_neg_integer()</tt></p>
|
||||
|
||||
|
||||
<h3 class="typedecl"><a name="type-file_prefix">file_prefix()</a></h3>
|
||||
<p><tt>file_prefix() = binary() | list()</tt></p>
|
||||
|
||||
|
||||
<h3 class="typedecl"><a name="type-file_size">file_size()</a></h3>
|
||||
<p><tt>file_size() = non_neg_integer()</tt></p>
|
||||
|
||||
|
||||
<h3 class="typedecl"><a name="type-inet_host">inet_host()</a></h3>
|
||||
<p><tt>inet_host() = <a href="inet.html#type-ip_address">inet:ip_address()</a> | <a href="inet.html#type-hostname">inet:hostname()</a></tt></p>
|
||||
|
||||
|
||||
<h3 class="typedecl"><a name="type-inet_port">inet_port()</a></h3>
|
||||
<p><tt>inet_port() = <a href="inet.html#type-port_number">inet:port_number()</a></tt></p>
|
||||
|
||||
|
||||
<h3 class="typedecl"><a name="type-projection">projection()</a></h3>
|
||||
<p><tt>projection() = #projection_v1{}</tt></p>
|
||||
|
||||
|
||||
<h3 class="typedecl"><a name="type-projection_type">projection_type()</a></h3>
|
||||
<p><tt>projection_type() = public | private</tt></p>
|
||||
|
||||
|
||||
<h2><a name="index">Function Index</a></h2>
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#append_chunk-4">append_chunk/4</a></td><td>Append a chunk (binary- or iolist-style) of data to a file
|
||||
with <code>Prefix</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#append_chunk-5">append_chunk/5</a></td><td>Append a chunk (binary- or iolist-style) of data to a file
|
||||
with <code>Prefix</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#checksum_list-3">checksum_list/3</a></td><td>Fetch the list of chunk checksums for <code>File</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#checksum_list-4">checksum_list/4</a></td><td>Fetch the list of chunk checksums for <code>File</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#delete_migration-3">delete_migration/3</a></td><td>Restricted API: Delete a file after it has been successfully
|
||||
migrated.</td></tr>
|
||||
<tr><td valign="top"><a href="#delete_migration-4">delete_migration/4</a></td><td>Restricted API: Delete a file after it has been successfully
|
||||
migrated.</td></tr>
|
||||
<tr><td valign="top"><a href="#get_all_projections-2">get_all_projections/2</a></td><td>Get all projections from the FLU's projection store.</td></tr>
|
||||
<tr><td valign="top"><a href="#get_all_projections-3">get_all_projections/3</a></td><td>Get all projections from the FLU's projection store.</td></tr>
|
||||
<tr><td valign="top"><a href="#get_latest_epoch-2">get_latest_epoch/2</a></td><td>Get the latest epoch number + checksum from the FLU's projection store.</td></tr>
|
||||
<tr><td valign="top"><a href="#get_latest_epoch-3">get_latest_epoch/3</a></td><td>Get the latest epoch number + checksum from the FLU's projection store.</td></tr>
|
||||
<tr><td valign="top"><a href="#list_all_projections-2">list_all_projections/2</a></td><td>Get all epoch numbers from the FLU's projection store.</td></tr>
|
||||
<tr><td valign="top"><a href="#list_all_projections-3">list_all_projections/3</a></td><td>Get all epoch numbers from the FLU's projection store.</td></tr>
|
||||
<tr><td valign="top"><a href="#list_files-2">list_files/2</a></td><td>Fetch the list of all files on the remote FLU.</td></tr>
|
||||
<tr><td valign="top"><a href="#list_files-3">list_files/3</a></td><td>Fetch the list of all files on the remote FLU.</td></tr>
|
||||
<tr><td valign="top"><a href="#quit-1">quit/1</a></td><td>Quit & close the connection to remote FLU.</td></tr>
|
||||
<tr><td valign="top"><a href="#read_chunk-5">read_chunk/5</a></td><td>Read a chunk of data of size <code>Size</code> from <code>File</code> at <code>Offset</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#read_chunk-6">read_chunk/6</a></td><td>Read a chunk of data of size <code>Size</code> from <code>File</code> at <code>Offset</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#read_latest_projection-2">read_latest_projection/2</a></td><td>Get the latest projection from the FLU's projection store for <code>ProjType</code></td></tr>
|
||||
<tr><td valign="top"><a href="#read_latest_projection-3">read_latest_projection/3</a></td><td>Get the latest projection from the FLU's projection store for <code>ProjType</code></td></tr>
|
||||
<tr><td valign="top"><a href="#read_projection-3">read_projection/3</a></td><td>Read a projection <code>Proj</code> of type <code>ProjType</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#read_projection-4">read_projection/4</a></td><td>Read a projection <code>Proj</code> of type <code>ProjType</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#trunc_hack-3">trunc_hack/3</a></td><td>Restricted API: Truncate a file after it has been successfully
|
||||
erasure coded.</td></tr>
|
||||
<tr><td valign="top"><a href="#trunc_hack-4">trunc_hack/4</a></td><td>Restricted API: Truncate a file after it has been successfully
|
||||
erasure coded.</td></tr>
|
||||
<tr><td valign="top"><a href="#write_chunk-5">write_chunk/5</a></td><td>Restricted API: Write a chunk of already-sequenced data to
|
||||
<code>File</code> at <code>Offset</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#write_chunk-6">write_chunk/6</a></td><td>Restricted API: Write a chunk of already-sequenced data to
|
||||
<code>File</code> at <code>Offset</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#write_projection-3">write_projection/3</a></td><td>Write a projection <code>Proj</code> of type <code>ProjType</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#write_projection-4">write_projection/4</a></td><td>Write a projection <code>Proj</code> of type <code>ProjType</code>.</td></tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="functions">Function Details</a></h2>
|
||||
|
||||
<h3 class="function"><a name="append_chunk-4">append_chunk/4</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>append_chunk(Sock::port(), EpochID::<a href="#type-epoch_id">epoch_id()</a>, Prefix::<a href="#type-file_prefix">file_prefix()</a>, Chunk::<a href="#type-chunk">chunk()</a>) -> {ok, <a href="#type-chunk_pos">chunk_pos()</a>} | {error, term()}</tt><br></p>
|
||||
</div><p>Append a chunk (binary- or iolist-style) of data to a file
|
||||
with <code>Prefix</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="append_chunk-5">append_chunk/5</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>append_chunk(Host::<a href="#type-inet_host">inet_host()</a>, TcpPort::<a href="#type-inet_port">inet_port()</a>, EpochID::<a href="#type-epoch_id">epoch_id()</a>, Prefix::<a href="#type-file_prefix">file_prefix()</a>, Chunk::<a href="#type-chunk">chunk()</a>) -> {ok, <a href="#type-chunk_pos">chunk_pos()</a>} | {error, term()}</tt><br></p>
|
||||
</div><p>Append a chunk (binary- or iolist-style) of data to a file
|
||||
with <code>Prefix</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="checksum_list-3">checksum_list/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>checksum_list(Sock::port(), EpochID::<a href="#type-epoch_id">epoch_id()</a>, File::<a href="#type-file_name">file_name()</a>) -> {ok, [<a href="#type-chunk_csum">chunk_csum()</a>]} | {error, term()}</tt><br></p>
|
||||
</div><p>Fetch the list of chunk checksums for <code>File</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="checksum_list-4">checksum_list/4</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>checksum_list(Host::<a href="#type-inet_host">inet_host()</a>, TcpPort::<a href="#type-inet_port">inet_port()</a>, EpochID::<a href="#type-epoch_id">epoch_id()</a>, File::<a href="#type-file_name">file_name()</a>) -> {ok, [<a href="#type-chunk_csum">chunk_csum()</a>]} | {error, term()}</tt><br></p>
|
||||
</div><p>Fetch the list of chunk checksums for <code>File</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="delete_migration-3">delete_migration/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>delete_migration(Sock::port(), EpochID::<a href="#type-epoch_id">epoch_id()</a>, File::<a href="#type-file_name">file_name()</a>) -> ok | {error, term()}</tt><br></p>
|
||||
</div><p>Restricted API: Delete a file after it has been successfully
|
||||
migrated.</p>
|
||||
|
||||
<h3 class="function"><a name="delete_migration-4">delete_migration/4</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>delete_migration(Host::<a href="#type-inet_host">inet_host()</a>, TcpPort::<a href="#type-inet_port">inet_port()</a>, EpochID::<a href="#type-epoch_id">epoch_id()</a>, File::<a href="#type-file_name">file_name()</a>) -> ok | {error, term()}</tt><br></p>
|
||||
</div><p>Restricted API: Delete a file after it has been successfully
|
||||
migrated.</p>
|
||||
|
||||
<h3 class="function"><a name="get_all_projections-2">get_all_projections/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>get_all_projections(Sock::port(), ProjType::<a href="#type-projection_type">projection_type()</a>) -> {ok, [<a href="#type-projection">projection()</a>]} | {error, term()}</tt><br></p>
|
||||
</div><p>Get all projections from the FLU's projection store.</p>
|
||||
|
||||
<h3 class="function"><a name="get_all_projections-3">get_all_projections/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>get_all_projections(Host::<a href="#type-inet_host">inet_host()</a>, TcpPort::<a href="#type-inet_port">inet_port()</a>, ProjType::<a href="#type-projection_type">projection_type()</a>) -> {ok, [<a href="#type-projection">projection()</a>]} | {error, term()}</tt><br></p>
|
||||
</div><p>Get all projections from the FLU's projection store.</p>
|
||||
|
||||
<h3 class="function"><a name="get_latest_epoch-2">get_latest_epoch/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>get_latest_epoch(Sock::port(), ProjType::<a href="#type-projection_type">projection_type()</a>) -> {ok, <a href="#type-epoch_id">epoch_id()</a>} | {error, term()}</tt><br></p>
|
||||
</div><p>Get the latest epoch number + checksum from the FLU's projection store.</p>
|
||||
|
||||
<h3 class="function"><a name="get_latest_epoch-3">get_latest_epoch/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>get_latest_epoch(Host::<a href="#type-inet_host">inet_host()</a>, TcpPort::<a href="#type-inet_port">inet_port()</a>, ProjType::<a href="#type-projection_type">projection_type()</a>) -> {ok, <a href="#type-epoch_id">epoch_id()</a>} | {error, term()}</tt><br></p>
|
||||
</div><p>Get the latest epoch number + checksum from the FLU's projection store.</p>
|
||||
|
||||
<h3 class="function"><a name="list_all_projections-2">list_all_projections/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>list_all_projections(Sock::port(), ProjType::<a href="#type-projection_type">projection_type()</a>) -> {ok, [non_neg_integer()]} | {error, term()}</tt><br></p>
|
||||
</div><p>Get all epoch numbers from the FLU's projection store.</p>
|
||||
|
||||
<h3 class="function"><a name="list_all_projections-3">list_all_projections/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>list_all_projections(Host::<a href="#type-inet_host">inet_host()</a>, TcpPort::<a href="#type-inet_port">inet_port()</a>, ProjType::<a href="#type-projection_type">projection_type()</a>) -> {ok, [non_neg_integer()]} | {error, term()}</tt><br></p>
|
||||
</div><p>Get all epoch numbers from the FLU's projection store.</p>
|
||||
|
||||
<h3 class="function"><a name="list_files-2">list_files/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>list_files(Sock::port(), EpochID::<a href="#type-epoch_id">epoch_id()</a>) -> {ok, [<a href="#type-file_info">file_info()</a>]} | {error, term()}</tt><br></p>
|
||||
</div><p>Fetch the list of all files on the remote FLU.</p>
|
||||
|
||||
<h3 class="function"><a name="list_files-3">list_files/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>list_files(Host::<a href="#type-inet_host">inet_host()</a>, TcpPort::<a href="#type-inet_port">inet_port()</a>, EpochID::<a href="#type-epoch_id">epoch_id()</a>) -> {ok, [<a href="#type-file_info">file_info()</a>]} | {error, term()}</tt><br></p>
|
||||
</div><p>Fetch the list of all files on the remote FLU.</p>
|
||||
|
||||
<h3 class="function"><a name="quit-1">quit/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>quit(Sock::port()) -> ok</tt><br></p>
|
||||
</div><p>Quit & close the connection to remote FLU.</p>
|
||||
|
||||
<h3 class="function"><a name="read_chunk-5">read_chunk/5</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>read_chunk(Sock::port(), EpochID::<a href="#type-epoch_id">epoch_id()</a>, File::<a href="#type-file_name">file_name()</a>, Offset::<a href="#type-file_offset">file_offset()</a>, Size::<a href="#type-chunk_size">chunk_size()</a>) -> {ok, <a href="#type-chunk_s">chunk_s()</a>} | {error, term()}</tt><br></p>
|
||||
</div><p>Read a chunk of data of size <code>Size</code> from <code>File</code> at <code>Offset</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="read_chunk-6">read_chunk/6</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>read_chunk(Host::<a href="#type-inet_host">inet_host()</a>, TcpPort::<a href="#type-inet_port">inet_port()</a>, EpochID::<a href="#type-epoch_id">epoch_id()</a>, File::<a href="#type-file_name">file_name()</a>, Offset::<a href="#type-file_offset">file_offset()</a>, Size::<a href="#type-chunk_size">chunk_size()</a>) -> {ok, <a href="#type-chunk_s">chunk_s()</a>} | {error, term()}</tt><br></p>
|
||||
</div><p>Read a chunk of data of size <code>Size</code> from <code>File</code> at <code>Offset</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="read_latest_projection-2">read_latest_projection/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>read_latest_projection(Sock::port(), ProjType::<a href="#type-projection_type">projection_type()</a>) -> {ok, <a href="#type-projection">projection()</a>} | {error, not_written} | {error, term()}</tt><br></p>
|
||||
</div><p>Get the latest projection from the FLU's projection store for <code>ProjType</code></p>
|
||||
|
||||
<h3 class="function"><a name="read_latest_projection-3">read_latest_projection/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>read_latest_projection(Host::<a href="#type-inet_host">inet_host()</a>, TcpPort::<a href="#type-inet_port">inet_port()</a>, ProjType::<a href="#type-projection_type">projection_type()</a>) -> {ok, <a href="#type-projection">projection()</a>} | {error, not_written} | {error, term()}</tt><br></p>
|
||||
</div><p>Get the latest projection from the FLU's projection store for <code>ProjType</code></p>
|
||||
|
||||
<h3 class="function"><a name="read_projection-3">read_projection/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>read_projection(Sock::port(), ProjType::<a href="#type-projection_type">projection_type()</a>, Epoch::<a href="#type-epoch_num">epoch_num()</a>) -> {ok, <a href="#type-projection">projection()</a>} | {error, written} | {error, term()}</tt><br></p>
|
||||
</div><p>Read a projection <code>Proj</code> of type <code>ProjType</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="read_projection-4">read_projection/4</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>read_projection(Host::<a href="#type-inet_host">inet_host()</a>, TcpPort::<a href="#type-inet_port">inet_port()</a>, ProjType::<a href="#type-projection_type">projection_type()</a>, Epoch::<a href="#type-epoch_num">epoch_num()</a>) -> {ok, <a href="#type-projection">projection()</a>} | {error, written} | {error, term()}</tt><br></p>
|
||||
</div><p>Read a projection <code>Proj</code> of type <code>ProjType</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="trunc_hack-3">trunc_hack/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>trunc_hack(Sock::port(), EpochID::<a href="#type-epoch_id">epoch_id()</a>, File::<a href="#type-file_name">file_name()</a>) -> ok | {error, term()}</tt><br></p>
|
||||
</div><p>Restricted API: Truncate a file after it has been successfully
|
||||
erasure coded.</p>
|
||||
|
||||
<h3 class="function"><a name="trunc_hack-4">trunc_hack/4</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>trunc_hack(Host::<a href="#type-inet_host">inet_host()</a>, TcpPort::<a href="#type-inet_port">inet_port()</a>, EpochID::<a href="#type-epoch_id">epoch_id()</a>, File::<a href="#type-file_name">file_name()</a>) -> ok | {error, term()}</tt><br></p>
|
||||
</div><p>Restricted API: Truncate a file after it has been successfully
|
||||
erasure coded.</p>
|
||||
|
||||
<h3 class="function"><a name="write_chunk-5">write_chunk/5</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>write_chunk(Sock::port(), EpochID::<a href="#type-epoch_id">epoch_id()</a>, File::<a href="#type-file_name">file_name()</a>, Offset::<a href="#type-file_offset">file_offset()</a>, Chunk::<a href="#type-chunk">chunk()</a>) -> ok | {error, term()}</tt><br></p>
|
||||
</div><p>Restricted API: Write a chunk of already-sequenced data to
|
||||
<code>File</code> at <code>Offset</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="write_chunk-6">write_chunk/6</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>write_chunk(Host::<a href="#type-inet_host">inet_host()</a>, TcpPort::<a href="#type-inet_port">inet_port()</a>, EpochID::<a href="#type-epoch_id">epoch_id()</a>, File::<a href="#type-file_name">file_name()</a>, Offset::<a href="#type-file_offset">file_offset()</a>, Chunk::<a href="#type-chunk">chunk()</a>) -> ok | {error, term()}</tt><br></p>
|
||||
</div><p>Restricted API: Write a chunk of already-sequenced data to
|
||||
<code>File</code> at <code>Offset</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="write_projection-3">write_projection/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>write_projection(Sock::port(), ProjType::<a href="#type-projection_type">projection_type()</a>, Proj::<a href="#type-projection">projection()</a>) -> ok | {error, written} | {error, term()}</tt><br></p>
|
||||
</div><p>Write a projection <code>Proj</code> of type <code>ProjType</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="write_projection-4">write_projection/4</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>write_projection(Host::<a href="#type-inet_host">inet_host()</a>, TcpPort::<a href="#type-inet_port">inet_port()</a>, ProjType::<a href="#type-projection_type">projection_type()</a>, Proj::<a href="#type-projection">projection()</a>) -> ok | {error, written} | {error, term()}</tt><br></p>
|
||||
</div><p>Write a projection <code>Proj</code> of type <code>ProjType</code>.</p>
|
||||
<hr>
|
||||
|
||||
<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<p><i>Generated by EDoc, Apr 8 2015, 17:31:11.</i></p>
|
||||
</body>
|
||||
</html>
|
41
edoc/machi_flu_sup.html
Normal file
41
edoc/machi_flu_sup.html
Normal file
|
@ -0,0 +1,41 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Module machi_flu_sup</title>
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<hr>
|
||||
|
||||
<h1>Module machi_flu_sup</h1>
|
||||
<ul class="index"><li><a href="#description">Description</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>Supervisor for Machi FLU servers and their related support
|
||||
servers.
|
||||
|
||||
<p><b>Behaviours:</b> <a href="supervisor.html"><tt>supervisor</tt></a>.</p>
|
||||
|
||||
<h2><a name="description">Description</a></h2>Supervisor for Machi FLU servers and their related support
|
||||
servers.
|
||||
<h2><a name="index">Function Index</a></h2>
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#init-1">init/1</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#start_link-0">start_link/0</a></td><td></td></tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="functions">Function Details</a></h2>
|
||||
|
||||
<h3 class="function"><a name="init-1">init/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>init(X1) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="start_link-0">start_link/0</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>start_link() -> any()</tt></p>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<p><i>Generated by EDoc, Apr 8 2015, 17:31:11.</i></p>
|
||||
</body>
|
||||
</html>
|
70
edoc/machi_projection.html
Normal file
70
edoc/machi_projection.html
Normal file
|
@ -0,0 +1,70 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Module machi_projection</title>
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<hr>
|
||||
|
||||
<h1>Module machi_projection</h1>
|
||||
<ul class="index"><li><a href="#description">Description</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>API for manipulating Machi projection data structures (i.e., records).
|
||||
|
||||
|
||||
<h2><a name="description">Description</a></h2>API for manipulating Machi projection data structures (i.e., records).
|
||||
<h2><a name="index">Function Index</a></h2>
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#compare-2">compare/2</a></td><td>Compare two projection records for equality (assuming that the
|
||||
checksum element has been correctly calculated).</td></tr>
|
||||
<tr><td valign="top"><a href="#make_projection_summary-1">make_projection_summary/1</a></td><td>Create a proplist-style summary of a projection record.</td></tr>
|
||||
<tr><td valign="top"><a href="#new-6">new/6</a></td><td>Create a new projection record.</td></tr>
|
||||
<tr><td valign="top"><a href="#new-7">new/7</a></td><td>Create a new projection record.</td></tr>
|
||||
<tr><td valign="top"><a href="#new-8">new/8</a></td><td>Create a new projection record.</td></tr>
|
||||
<tr><td valign="top"><a href="#update_projection_checksum-1">update_projection_checksum/1</a></td><td>Update the checksum element of a projection record.</td></tr>
|
||||
<tr><td valign="top"><a href="#update_projection_dbg2-2">update_projection_dbg2/2</a></td><td>Update the <code>dbg2</code> element of a projection record.</td></tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="functions">Function Details</a></h2>
|
||||
|
||||
<h3 class="function"><a name="compare-2">compare/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>compare(Projection_v1::#projection_v1{}, Projection_v1::#projection_v1{}) -> integer()</tt><br></p>
|
||||
</div><p>Compare two projection records for equality (assuming that the
|
||||
checksum element has been correctly calculated).</p>
|
||||
|
||||
<h3 class="function"><a name="make_projection_summary-1">make_projection_summary/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>make_projection_summary(Projection_v1) -> any()</tt></p>
|
||||
</div><p>Create a proplist-style summary of a projection record.</p>
|
||||
|
||||
<h3 class="function"><a name="new-6">new/6</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>new(MyName, All_list, UPI_list, Down_list, Repairing_list, Ps) -> any()</tt></p>
|
||||
</div><p>Create a new projection record.</p>
|
||||
|
||||
<h3 class="function"><a name="new-7">new/7</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>new(EpochNum, MyName, All_list, Down_list, UPI_list, Repairing_list, Dbg) -> any()</tt></p>
|
||||
</div><p>Create a new projection record.</p>
|
||||
|
||||
<h3 class="function"><a name="new-8">new/8</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>new(EpochNum, MyName, All_list0, Down_list, UPI_list, Repairing_list, Dbg, Dbg2) -> any()</tt></p>
|
||||
</div><p>Create a new projection record.</p>
|
||||
|
||||
<h3 class="function"><a name="update_projection_checksum-1">update_projection_checksum/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>update_projection_checksum(P) -> any()</tt></p>
|
||||
</div><p>Update the checksum element of a projection record.</p>
|
||||
|
||||
<h3 class="function"><a name="update_projection_dbg2-2">update_projection_dbg2/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>update_projection_dbg2(P, Dbg2) -> any()</tt></p>
|
||||
</div><p>Update the <code>dbg2</code> element of a projection record.</p>
|
||||
<hr>
|
||||
|
||||
<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<p><i>Generated by EDoc, Apr 8 2015, 17:31:11.</i></p>
|
||||
</body>
|
||||
</html>
|
163
edoc/machi_projection_store.html
Normal file
163
edoc/machi_projection_store.html
Normal file
|
@ -0,0 +1,163 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Module machi_projection_store</title>
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<hr>
|
||||
|
||||
<h1>Module machi_projection_store</h1>
|
||||
<ul class="index"><li><a href="#description">Description</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>The Machi write-once projection store service.
|
||||
|
||||
|
||||
<h2><a name="description">Description</a></h2><p>The Machi write-once projection store service.</p>
|
||||
|
||||
<p>This API is gen_server-style message passing, intended for use
|
||||
within a single Erlang node to glue together the projection store
|
||||
server with the node-local process that implements Machi's TCP
|
||||
client access protocol (on the "server side" of the TCP connection).</p>
|
||||
|
||||
<p>All Machi client access to the projection store SHOULD NOT use this
|
||||
module's API.</p>
|
||||
|
||||
The projection store is implemented by an Erlang/OTP <code>gen_server</code>
|
||||
process that is associated with each FLU. Conceptually, the
|
||||
projection store is an array of write-once registers. For each
|
||||
projection store register, the key is a 2-tuple of an epoch number
|
||||
(<code>non_neg_integer()</code> type) and a projection type (<code>public</code> or
|
||||
<code>private</code> type); the value is a projection data structure
|
||||
(<code>projection_v1()</code> type).
|
||||
<h2><a name="index">Function Index</a></h2>
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#code_change-3">code_change/3</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#get_all_projections-2">get_all_projections/2</a></td><td>Fetch all projection records of type <code>ProjType</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#get_all_projections-3">get_all_projections/3</a></td><td>Fetch all projection records of type <code>ProjType</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#get_latest_epoch-2">get_latest_epoch/2</a></td><td>Fetch the latest epoch number + checksum for type <code>ProjType</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#get_latest_epoch-3">get_latest_epoch/3</a></td><td>Fetch the latest epoch number + checksum for type <code>ProjType</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#handle_call-3">handle_call/3</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#handle_cast-2">handle_cast/2</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#handle_info-2">handle_info/2</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#init-1">init/1</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#list_all_projections-2">list_all_projections/2</a></td><td>Fetch all projection epoch numbers of type <code>ProjType</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#list_all_projections-3">list_all_projections/3</a></td><td>Fetch all projection epoch numbers of type <code>ProjType</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#read-3">read/3</a></td><td>Fetch the projection record type <code>ProjType</code> for epoch number <code>Epoch</code> .</td></tr>
|
||||
<tr><td valign="top"><a href="#read-4">read/4</a></td><td>Fetch the projection record type <code>ProjType</code> for epoch number <code>Epoch</code> .</td></tr>
|
||||
<tr><td valign="top"><a href="#read_latest_projection-2">read_latest_projection/2</a></td><td>Fetch the latest projection record for type <code>ProjType</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#read_latest_projection-3">read_latest_projection/3</a></td><td>Fetch the latest projection record for type <code>ProjType</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#start_link-3">start_link/3</a></td><td>Start a new projection store server.</td></tr>
|
||||
<tr><td valign="top"><a href="#terminate-2">terminate/2</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#write-3">write/3</a></td><td>Write the projection record type <code>ProjType</code> for epoch number <code>Epoch</code> .</td></tr>
|
||||
<tr><td valign="top"><a href="#write-4">write/4</a></td><td>Write the projection record type <code>ProjType</code> for epoch number <code>Epoch</code> .</td></tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="functions">Function Details</a></h2>
|
||||
|
||||
<h3 class="function"><a name="code_change-3">code_change/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>code_change(OldVsn, S, Extra) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="get_all_projections-2">get_all_projections/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>get_all_projections(PidSpec, ProjType) -> any()</tt></p>
|
||||
</div><p>Fetch all projection records of type <code>ProjType</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="get_all_projections-3">get_all_projections/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>get_all_projections(PidSpec, ProjType, Timeout) -> any()</tt></p>
|
||||
</div><p>Fetch all projection records of type <code>ProjType</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="get_latest_epoch-2">get_latest_epoch/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>get_latest_epoch(PidSpec, ProjType) -> any()</tt></p>
|
||||
</div><p>Fetch the latest epoch number + checksum for type <code>ProjType</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="get_latest_epoch-3">get_latest_epoch/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>get_latest_epoch(PidSpec, ProjType, Timeout) -> any()</tt></p>
|
||||
</div><p>Fetch the latest epoch number + checksum for type <code>ProjType</code>.
|
||||
projection.</p>
|
||||
|
||||
<h3 class="function"><a name="handle_call-3">handle_call/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>handle_call(Request, From, S) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="handle_cast-2">handle_cast/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>handle_cast(Msg, S) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="handle_info-2">handle_info/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>handle_info(Info, S) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="init-1">init/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>init(X1) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="list_all_projections-2">list_all_projections/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>list_all_projections(PidSpec, ProjType) -> any()</tt></p>
|
||||
</div><p>Fetch all projection epoch numbers of type <code>ProjType</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="list_all_projections-3">list_all_projections/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>list_all_projections(PidSpec, ProjType, Timeout) -> any()</tt></p>
|
||||
</div><p>Fetch all projection epoch numbers of type <code>ProjType</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="read-3">read/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>read(PidSpec, ProjType, Epoch) -> any()</tt></p>
|
||||
</div><p>Fetch the projection record type <code>ProjType</code> for epoch number <code>Epoch</code> .</p>
|
||||
|
||||
<h3 class="function"><a name="read-4">read/4</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>read(PidSpec, ProjType, Epoch, Timeout) -> any()</tt></p>
|
||||
</div><p>Fetch the projection record type <code>ProjType</code> for epoch number <code>Epoch</code> .</p>
|
||||
|
||||
<h3 class="function"><a name="read_latest_projection-2">read_latest_projection/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>read_latest_projection(PidSpec, ProjType) -> any()</tt></p>
|
||||
</div><p>Fetch the latest projection record for type <code>ProjType</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="read_latest_projection-3">read_latest_projection/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>read_latest_projection(PidSpec, ProjType, Timeout) -> any()</tt></p>
|
||||
</div><p>Fetch the latest projection record for type <code>ProjType</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="start_link-3">start_link/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>start_link(RegName, DataDir, NotifyWedgeStateChanges) -> any()</tt></p>
|
||||
</div><p><p>Start a new projection store server.</p>
|
||||
|
||||
The <code>DataDir</code> argument should be the same directory as specified
|
||||
for use by our companion FLU data server -- all file system paths
|
||||
used by this server are intended to be stored underneath a common
|
||||
file system parent directory as the FLU data server & sequencer
|
||||
servers.</p>
|
||||
|
||||
<h3 class="function"><a name="terminate-2">terminate/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>terminate(Reason, S) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="write-3">write/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>write(PidSpec, ProjType, Proj) -> any()</tt></p>
|
||||
</div><p>Write the projection record type <code>ProjType</code> for epoch number <code>Epoch</code> .</p>
|
||||
|
||||
<h3 class="function"><a name="write-4">write/4</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>write(PidSpec, ProjType, Proj, Timeout) -> any()</tt></p>
|
||||
</div><p>Write the projection record type <code>ProjType</code> for epoch number <code>Epoch</code> .</p>
|
||||
<hr>
|
||||
|
||||
<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<p><i>Generated by EDoc, Apr 8 2015, 17:31:11.</i></p>
|
||||
</body>
|
||||
</html>
|
222
edoc/machi_proxy_flu1_client.html
Normal file
222
edoc/machi_proxy_flu1_client.html
Normal file
|
@ -0,0 +1,222 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Module machi_proxy_flu1_client</title>
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<hr>
|
||||
|
||||
<h1>Module machi_proxy_flu1_client</h1>
|
||||
<ul class="index"><li><a href="#description">Description</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>Erlang API for the Machi FLU TCP protocol version 1, with a
|
||||
proxy-process style API for hiding messy details such as TCP
|
||||
connection/disconnection with the remote Machi server.
|
||||
|
||||
<p><b>Behaviours:</b> <a href="gen_server.html"><tt>gen_server</tt></a>.</p>
|
||||
|
||||
<h2><a name="description">Description</a></h2><p>Erlang API for the Machi FLU TCP protocol version 1, with a
|
||||
proxy-process style API for hiding messy details such as TCP
|
||||
connection/disconnection with the remote Machi server.</p>
|
||||
|
||||
<p>Machi is intentionally avoiding using distributed Erlang for
|
||||
Machi's communication. This design decision makes Erlang-side code
|
||||
more difficult & complex, but it's the price to pay for some
|
||||
language independence. Later in Machi's life cycle, we need to
|
||||
(re-)implement some components in a non-Erlang/BEAM-based language.</p>
|
||||
|
||||
This module implements a "man in the middle" proxy between the
|
||||
Erlang client and Machi server (which is on the "far side" of a TCP
|
||||
connection to somewhere). This proxy process will always execute
|
||||
on the same Erlang node as the Erlang client that uses it. The
|
||||
proxy is intended to be a stable, long-lived process that survives
|
||||
TCP communication problems with the remote server.
|
||||
<h2><a name="index">Function Index</a></h2>
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#append_chunk-4">append_chunk/4</a></td><td>Append a chunk (binary- or iolist-style) of data to a file
|
||||
with <code>Prefix</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#append_chunk-5">append_chunk/5</a></td><td>Append a chunk (binary- or iolist-style) of data to a file
|
||||
with <code>Prefix</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#checksum_list-3">checksum_list/3</a></td><td>Fetch the list of chunk checksums for <code>File</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#checksum_list-4">checksum_list/4</a></td><td>Fetch the list of chunk checksums for <code>File</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#code_change-3">code_change/3</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#get_all_projections-2">get_all_projections/2</a></td><td>Get all projections from the FLU's projection store.</td></tr>
|
||||
<tr><td valign="top"><a href="#get_all_projections-3">get_all_projections/3</a></td><td>Get all projections from the FLU's projection store.</td></tr>
|
||||
<tr><td valign="top"><a href="#get_latest_epoch-2">get_latest_epoch/2</a></td><td>Get the latest epoch number + checksum from the FLU's projection store.</td></tr>
|
||||
<tr><td valign="top"><a href="#get_latest_epoch-3">get_latest_epoch/3</a></td><td>Get the latest epoch number + checksum from the FLU's projection store.</td></tr>
|
||||
<tr><td valign="top"><a href="#handle_call-3">handle_call/3</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#handle_cast-2">handle_cast/2</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#handle_info-2">handle_info/2</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#init-1">init/1</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#list_all_projections-2">list_all_projections/2</a></td><td>Get all epoch numbers from the FLU's projection store.</td></tr>
|
||||
<tr><td valign="top"><a href="#list_all_projections-3">list_all_projections/3</a></td><td>Get all epoch numbers from the FLU's projection store.</td></tr>
|
||||
<tr><td valign="top"><a href="#list_files-2">list_files/2</a></td><td>Fetch the list of all files on the remote FLU.</td></tr>
|
||||
<tr><td valign="top"><a href="#list_files-3">list_files/3</a></td><td>Fetch the list of all files on the remote FLU.</td></tr>
|
||||
<tr><td valign="top"><a href="#quit-1">quit/1</a></td><td>Quit & close the connection to remote FLU and stop our
|
||||
proxy process.</td></tr>
|
||||
<tr><td valign="top"><a href="#read_chunk-5">read_chunk/5</a></td><td>Read a chunk of data of size <code>Size</code> from <code>File</code> at <code>Offset</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#read_chunk-6">read_chunk/6</a></td><td>Read a chunk of data of size <code>Size</code> from <code>File</code> at <code>Offset</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#read_latest_projection-2">read_latest_projection/2</a></td><td>Get the latest projection from the FLU's projection store for <code>ProjType</code></td></tr>
|
||||
<tr><td valign="top"><a href="#read_latest_projection-3">read_latest_projection/3</a></td><td>Get the latest projection from the FLU's projection store for <code>ProjType</code></td></tr>
|
||||
<tr><td valign="top"><a href="#read_projection-3">read_projection/3</a></td><td>Read a projection <code>Proj</code> of type <code>ProjType</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#read_projection-4">read_projection/4</a></td><td>Read a projection <code>Proj</code> of type <code>ProjType</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#start_link-1">start_link/1</a></td><td>Start a local, long-lived process that will be our steady
|
||||
& reliable communication proxy with the fickle & flaky
|
||||
remote Machi server.</td></tr>
|
||||
<tr><td valign="top"><a href="#terminate-2">terminate/2</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#write_projection-3">write_projection/3</a></td><td>Write a projection <code>Proj</code> of type <code>ProjType</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#write_projection-4">write_projection/4</a></td><td>Write a projection <code>Proj</code> of type <code>ProjType</code>.</td></tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="functions">Function Details</a></h2>
|
||||
|
||||
<h3 class="function"><a name="append_chunk-4">append_chunk/4</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>append_chunk(PidSpec, EpochID, Prefix, Chunk) -> any()</tt></p>
|
||||
</div><p>Append a chunk (binary- or iolist-style) of data to a file
|
||||
with <code>Prefix</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="append_chunk-5">append_chunk/5</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>append_chunk(PidSpec, EpochID, Prefix, Chunk, Timeout) -> any()</tt></p>
|
||||
</div><p>Append a chunk (binary- or iolist-style) of data to a file
|
||||
with <code>Prefix</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="checksum_list-3">checksum_list/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>checksum_list(PidSpec, EpochID, File) -> any()</tt></p>
|
||||
</div><p>Fetch the list of chunk checksums for <code>File</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="checksum_list-4">checksum_list/4</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>checksum_list(PidSpec, EpochID, File, Timeout) -> any()</tt></p>
|
||||
</div><p>Fetch the list of chunk checksums for <code>File</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="code_change-3">code_change/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>code_change(OldVsn, S, Extra) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="get_all_projections-2">get_all_projections/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>get_all_projections(PidSpec, ProjType) -> any()</tt></p>
|
||||
</div><p>Get all projections from the FLU's projection store.</p>
|
||||
|
||||
<h3 class="function"><a name="get_all_projections-3">get_all_projections/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>get_all_projections(PidSpec, ProjType, Timeout) -> any()</tt></p>
|
||||
</div><p>Get all projections from the FLU's projection store.</p>
|
||||
|
||||
<h3 class="function"><a name="get_latest_epoch-2">get_latest_epoch/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>get_latest_epoch(PidSpec, ProjType) -> any()</tt></p>
|
||||
</div><p>Get the latest epoch number + checksum from the FLU's projection store.</p>
|
||||
|
||||
<h3 class="function"><a name="get_latest_epoch-3">get_latest_epoch/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>get_latest_epoch(PidSpec, ProjType, Timeout) -> any()</tt></p>
|
||||
</div><p>Get the latest epoch number + checksum from the FLU's projection store.</p>
|
||||
|
||||
<h3 class="function"><a name="handle_call-3">handle_call/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>handle_call(Request, From, S) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="handle_cast-2">handle_cast/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>handle_cast(Msg, S) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="handle_info-2">handle_info/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>handle_info(Info, S) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="init-1">init/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>init(X1) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="list_all_projections-2">list_all_projections/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>list_all_projections(PidSpec, ProjType) -> any()</tt></p>
|
||||
</div><p>Get all epoch numbers from the FLU's projection store.</p>
|
||||
|
||||
<h3 class="function"><a name="list_all_projections-3">list_all_projections/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>list_all_projections(PidSpec, ProjType, Timeout) -> any()</tt></p>
|
||||
</div><p>Get all epoch numbers from the FLU's projection store.</p>
|
||||
|
||||
<h3 class="function"><a name="list_files-2">list_files/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>list_files(PidSpec, EpochID) -> any()</tt></p>
|
||||
</div><p>Fetch the list of all files on the remote FLU.</p>
|
||||
|
||||
<h3 class="function"><a name="list_files-3">list_files/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>list_files(PidSpec, EpochID, Timeout) -> any()</tt></p>
|
||||
</div><p>Fetch the list of all files on the remote FLU.</p>
|
||||
|
||||
<h3 class="function"><a name="quit-1">quit/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>quit(PidSpec) -> any()</tt></p>
|
||||
</div><p>Quit & close the connection to remote FLU and stop our
|
||||
proxy process.</p>
|
||||
|
||||
<h3 class="function"><a name="read_chunk-5">read_chunk/5</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>read_chunk(PidSpec, EpochID, File, Offset, Size) -> any()</tt></p>
|
||||
</div><p>Read a chunk of data of size <code>Size</code> from <code>File</code> at <code>Offset</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="read_chunk-6">read_chunk/6</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>read_chunk(PidSpec, EpochID, File, Offset, Size, Timeout) -> any()</tt></p>
|
||||
</div><p>Read a chunk of data of size <code>Size</code> from <code>File</code> at <code>Offset</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="read_latest_projection-2">read_latest_projection/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>read_latest_projection(PidSpec, ProjType) -> any()</tt></p>
|
||||
</div><p>Get the latest projection from the FLU's projection store for <code>ProjType</code></p>
|
||||
|
||||
<h3 class="function"><a name="read_latest_projection-3">read_latest_projection/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>read_latest_projection(PidSpec, ProjType, Timeout) -> any()</tt></p>
|
||||
</div><p>Get the latest projection from the FLU's projection store for <code>ProjType</code></p>
|
||||
|
||||
<h3 class="function"><a name="read_projection-3">read_projection/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>read_projection(PidSpec, ProjType, Epoch) -> any()</tt></p>
|
||||
</div><p>Read a projection <code>Proj</code> of type <code>ProjType</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="read_projection-4">read_projection/4</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>read_projection(PidSpec, ProjType, Epoch, Timeout) -> any()</tt></p>
|
||||
</div><p>Read a projection <code>Proj</code> of type <code>ProjType</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="start_link-1">start_link/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>start_link(P_srvr) -> any()</tt></p>
|
||||
</div><p>Start a local, long-lived process that will be our steady
|
||||
& reliable communication proxy with the fickle & flaky
|
||||
remote Machi server.</p>
|
||||
|
||||
<h3 class="function"><a name="terminate-2">terminate/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>terminate(Reason, S) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="write_projection-3">write_projection/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>write_projection(PidSpec, ProjType, Proj) -> any()</tt></p>
|
||||
</div><p>Write a projection <code>Proj</code> of type <code>ProjType</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="write_projection-4">write_projection/4</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>write_projection(PidSpec, ProjType, Proj, Timeout) -> any()</tt></p>
|
||||
</div><p>Write a projection <code>Proj</code> of type <code>ProjType</code>.</p>
|
||||
<hr>
|
||||
|
||||
<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<p><i>Generated by EDoc, Apr 8 2015, 17:31:11.</i></p>
|
||||
</body>
|
||||
</html>
|
23
edoc/machi_sequencer.html
Normal file
23
edoc/machi_sequencer.html
Normal file
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Module machi_sequencer</title>
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<hr>
|
||||
|
||||
<h1>Module machi_sequencer</h1>
|
||||
<ul class="index"><li><a href="#description">Description</a></li></ul>"Mothballed" sequencer code, perhaps to be reused sometime in
|
||||
the future?.
|
||||
|
||||
|
||||
<h2><a name="description">Description</a></h2>"Mothballed" sequencer code, perhaps to be reused sometime in
|
||||
the future?<hr>
|
||||
|
||||
<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<p><i>Generated by EDoc, Apr 8 2015, 17:31:11.</i></p>
|
||||
</body>
|
||||
</html>
|
39
edoc/machi_sup.html
Normal file
39
edoc/machi_sup.html
Normal file
|
@ -0,0 +1,39 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Module machi_sup</title>
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<hr>
|
||||
|
||||
<h1>Module machi_sup</h1>
|
||||
<ul class="index"><li><a href="#description">Description</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>Top Machi application supervisor.
|
||||
|
||||
<p><b>Behaviours:</b> <a href="supervisor.html"><tt>supervisor</tt></a>.</p>
|
||||
|
||||
<h2><a name="description">Description</a></h2>Top Machi application supervisor.
|
||||
<h2><a name="index">Function Index</a></h2>
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#init-1">init/1</a></td><td></td></tr>
|
||||
<tr><td valign="top"><a href="#start_link-0">start_link/0</a></td><td></td></tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="functions">Function Details</a></h2>
|
||||
|
||||
<h3 class="function"><a name="init-1">init/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>init(X1) -> any()</tt></p>
|
||||
</div>
|
||||
|
||||
<h3 class="function"><a name="start_link-0">start_link/0</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>start_link() -> any()</tt></p>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<p><i>Generated by EDoc, Apr 8 2015, 17:31:11.</i></p>
|
||||
</body>
|
||||
</html>
|
150
edoc/machi_util.html
Normal file
150
edoc/machi_util.html
Normal file
|
@ -0,0 +1,150 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Module machi_util</title>
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<hr>
|
||||
|
||||
<h1>Module machi_util</h1>
|
||||
<ul class="index"><li><a href="#description">Description</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul>Miscellaneous utility functions.
|
||||
|
||||
|
||||
<h2><a name="description">Description</a></h2>Miscellaneous utility functions.
|
||||
<h2><a name="index">Function Index</a></h2>
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#bin_to_hexstr-1">bin_to_hexstr/1</a></td><td>Convert a <code>binary()</code> to a hexadecimal string.</td></tr>
|
||||
<tr><td valign="top"><a href="#checksum_chunk-1">checksum_chunk/1</a></td><td>Calculate a checksum for a chunk of file data.</td></tr>
|
||||
<tr><td valign="top"><a href="#connect-2">connect/2</a></td><td>Create a TCP connection to a remote Machi server.</td></tr>
|
||||
<tr><td valign="top"><a href="#connect-3">connect/3</a></td><td>Create a TCP connection to a remote Machi server.</td></tr>
|
||||
<tr><td valign="top"><a href="#hexstr_to_bin-1">hexstr_to_bin/1</a></td><td>Convert a hexadecimal string to a <code>binary()</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#hexstr_to_int-1">hexstr_to_int/1</a></td><td>Convert a hexadecimal string to an integer.</td></tr>
|
||||
<tr><td valign="top"><a href="#increment_max_filenum-2">increment_max_filenum/2</a></td><td>Increase the file size of a config file, which is used as the
|
||||
basis for a minimum sequence number.</td></tr>
|
||||
<tr><td valign="top"><a href="#info_msg-2">info_msg/2</a></td><td>Log an 'info' level message.</td></tr>
|
||||
<tr><td valign="top"><a href="#int_to_hexbin-2">int_to_hexbin/2</a></td><td>Convert an integer into a hexadecimal string (in <code>binary()</code>
|
||||
form) whose length is based on <code>I_size</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#int_to_hexstr-2">int_to_hexstr/2</a></td><td>Convert an integer into a hexadecimal string whose length is
|
||||
based on <code>I_size</code>.</td></tr>
|
||||
<tr><td valign="top"><a href="#make_binary-1">make_binary/1</a></td><td>Convert a compatible Erlang data type into a <code>binary()</code> equivalent.</td></tr>
|
||||
<tr><td valign="top"><a href="#make_checksum_filename-2">make_checksum_filename/2</a></td><td>Calculate a checksum file path, by common convention.</td></tr>
|
||||
<tr><td valign="top"><a href="#make_data_filename-2">make_data_filename/2</a></td><td>Calculate a file data file path, by common convention.</td></tr>
|
||||
<tr><td valign="top"><a href="#make_projection_filename-2">make_projection_filename/2</a></td><td>Calculate a projection store file path, by common convention.</td></tr>
|
||||
<tr><td valign="top"><a href="#make_regname-1">make_regname/1</a></td><td>Create a registered name atom for FLU sequencer internal
|
||||
rendezvous/message passing use.</td></tr>
|
||||
<tr><td valign="top"><a href="#make_string-1">make_string/1</a></td><td>Convert a compatible Erlang data type into a <code>string()</code> equivalent.</td></tr>
|
||||
<tr><td valign="top"><a href="#read_max_filenum-2">read_max_filenum/2</a></td><td>Read the file size of a config file, which is used as the
|
||||
basis for a minimum sequence number.</td></tr>
|
||||
<tr><td valign="top"><a href="#verb-1">verb/1</a></td><td>Log a verbose message.</td></tr>
|
||||
<tr><td valign="top"><a href="#verb-2">verb/2</a></td><td>Log a verbose message.</td></tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="functions">Function Details</a></h2>
|
||||
|
||||
<h3 class="function"><a name="bin_to_hexstr-1">bin_to_hexstr/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>bin_to_hexstr(X1) -> any()</tt></p>
|
||||
</div><p>Convert a <code>binary()</code> to a hexadecimal string.</p>
|
||||
|
||||
<h3 class="function"><a name="checksum_chunk-1">checksum_chunk/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>checksum_chunk(Chunk) -> any()</tt></p>
|
||||
</div><p>Calculate a checksum for a chunk of file data.</p>
|
||||
|
||||
<h3 class="function"><a name="connect-2">connect/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>connect(Host::<a href="inet.html#type-ip_address">inet:ip_address()</a> | <a href="inet.html#type-hostname">inet:hostname()</a>, Port::<a href="inet.html#type-port_number">inet:port_number()</a>) -> port()</tt><br></p>
|
||||
</div><p>Create a TCP connection to a remote Machi server.</p>
|
||||
|
||||
<h3 class="function"><a name="connect-3">connect/3</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>connect(Host::<a href="inet.html#type-ip_address">inet:ip_address()</a> | <a href="inet.html#type-hostname">inet:hostname()</a>, Port::<a href="inet.html#type-port_number">inet:port_number()</a>, Timeout::timeout()) -> port()</tt><br></p>
|
||||
</div><p>Create a TCP connection to a remote Machi server.</p>
|
||||
|
||||
<h3 class="function"><a name="hexstr_to_bin-1">hexstr_to_bin/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>hexstr_to_bin(S) -> any()</tt></p>
|
||||
</div><p>Convert a hexadecimal string to a <code>binary()</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="hexstr_to_int-1">hexstr_to_int/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>hexstr_to_int(X) -> any()</tt></p>
|
||||
</div><p>Convert a hexadecimal string to an integer.</p>
|
||||
|
||||
<h3 class="function"><a name="increment_max_filenum-2">increment_max_filenum/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>increment_max_filenum(DataDir, Prefix) -> any()</tt></p>
|
||||
</div><p>Increase the file size of a config file, which is used as the
|
||||
basis for a minimum sequence number.</p>
|
||||
|
||||
<h3 class="function"><a name="info_msg-2">info_msg/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>info_msg(Fmt, Args) -> any()</tt></p>
|
||||
</div><p>Log an 'info' level message.</p>
|
||||
|
||||
<h3 class="function"><a name="int_to_hexbin-2">int_to_hexbin/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>int_to_hexbin(I, I_size) -> any()</tt></p>
|
||||
</div><p>Convert an integer into a hexadecimal string (in <code>binary()</code>
|
||||
form) whose length is based on <code>I_size</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="int_to_hexstr-2">int_to_hexstr/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>int_to_hexstr(I, I_size) -> any()</tt></p>
|
||||
</div><p>Convert an integer into a hexadecimal string whose length is
|
||||
based on <code>I_size</code>.</p>
|
||||
|
||||
<h3 class="function"><a name="make_binary-1">make_binary/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>make_binary(X) -> any()</tt></p>
|
||||
</div><p>Convert a compatible Erlang data type into a <code>binary()</code> equivalent.</p>
|
||||
|
||||
<h3 class="function"><a name="make_checksum_filename-2">make_checksum_filename/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>make_checksum_filename(DataDir, FileName) -> any()</tt></p>
|
||||
</div><p>Calculate a checksum file path, by common convention.</p>
|
||||
|
||||
<h3 class="function"><a name="make_data_filename-2">make_data_filename/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>make_data_filename(DataDir, File) -> any()</tt></p>
|
||||
</div><p>Calculate a file data file path, by common convention.</p>
|
||||
|
||||
<h3 class="function"><a name="make_projection_filename-2">make_projection_filename/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>make_projection_filename(DataDir, File) -> any()</tt></p>
|
||||
</div><p>Calculate a projection store file path, by common convention.</p>
|
||||
|
||||
<h3 class="function"><a name="make_regname-1">make_regname/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>make_regname(Prefix) -> any()</tt></p>
|
||||
</div><p>Create a registered name atom for FLU sequencer internal
|
||||
rendezvous/message passing use.</p>
|
||||
|
||||
<h3 class="function"><a name="make_string-1">make_string/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>make_string(X) -> any()</tt></p>
|
||||
</div><p>Convert a compatible Erlang data type into a <code>string()</code> equivalent.</p>
|
||||
|
||||
<h3 class="function"><a name="read_max_filenum-2">read_max_filenum/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>read_max_filenum(DataDir, Prefix) -> any()</tt></p>
|
||||
</div><p>Read the file size of a config file, which is used as the
|
||||
basis for a minimum sequence number.</p>
|
||||
|
||||
<h3 class="function"><a name="verb-1">verb/1</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>verb(Fmt) -> any()</tt></p>
|
||||
</div><p>Log a verbose message.</p>
|
||||
|
||||
<h3 class="function"><a name="verb-2">verb/2</a></h3>
|
||||
<div class="spec">
|
||||
<p><tt>verb(Fmt, Args) -> any()</tt></p>
|
||||
</div><p>Log a verbose message.</p>
|
||||
<hr>
|
||||
|
||||
<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<p><i>Generated by EDoc, Apr 8 2015, 17:31:11.</i></p>
|
||||
</body>
|
||||
</html>
|
24
edoc/modules-frame.html
Normal file
24
edoc/modules-frame.html
Normal file
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>The machi application</title>
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<h2 class="indextitle">Modules</h2>
|
||||
<table width="100%" border="0" summary="list of modules">
|
||||
<tr><td><a href="machi_admin_util.html" target="overviewFrame" class="module">machi_admin_util</a></td></tr>
|
||||
<tr><td><a href="machi_app.html" target="overviewFrame" class="module">machi_app</a></td></tr>
|
||||
<tr><td><a href="machi_chain_manager1.html" target="overviewFrame" class="module">machi_chain_manager1</a></td></tr>
|
||||
<tr><td><a href="machi_chash.html" target="overviewFrame" class="module">machi_chash</a></td></tr>
|
||||
<tr><td><a href="machi_flu1.html" target="overviewFrame" class="module">machi_flu1</a></td></tr>
|
||||
<tr><td><a href="machi_flu1_client.html" target="overviewFrame" class="module">machi_flu1_client</a></td></tr>
|
||||
<tr><td><a href="machi_flu_sup.html" target="overviewFrame" class="module">machi_flu_sup</a></td></tr>
|
||||
<tr><td><a href="machi_projection.html" target="overviewFrame" class="module">machi_projection</a></td></tr>
|
||||
<tr><td><a href="machi_projection_store.html" target="overviewFrame" class="module">machi_projection_store</a></td></tr>
|
||||
<tr><td><a href="machi_proxy_flu1_client.html" target="overviewFrame" class="module">machi_proxy_flu1_client</a></td></tr>
|
||||
<tr><td><a href="machi_sequencer.html" target="overviewFrame" class="module">machi_sequencer</a></td></tr>
|
||||
<tr><td><a href="machi_sup.html" target="overviewFrame" class="module">machi_sup</a></td></tr>
|
||||
<tr><td><a href="machi_util.html" target="overviewFrame" class="module">machi_util</a></td></tr></table>
|
||||
</body>
|
||||
</html>
|
185
edoc/overview-summary.html
Normal file
185
edoc/overview-summary.html
Normal file
|
@ -0,0 +1,185 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Machi: a small village of replicated files
|
||||
</title>
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<h1>Machi: a small village of replicated files
|
||||
</h1>
|
||||
|
||||
|
||||
<h3><a name="About_This_EDoc_Documentation">About This EDoc Documentation</a></h3>
|
||||
|
||||
<p>This EDoc-style documentation will concern itself only with Erlang
|
||||
function APIs and function & data types. Higher-level design and
|
||||
commentary will remain outside of the Erlang EDoc system; please see
|
||||
the "Pointers to Other Machi Documentation" section below for more
|
||||
details.</p>
|
||||
|
||||
<p>Readers should beware that this documentation may be out-of-sync with
|
||||
the source code. When in doubt, use the <code>make edoc</code> command to
|
||||
regenerate all HTML pages.</p>
|
||||
|
||||
<p>It is the developer's responsibility to re-generate the documentation
|
||||
periodically and commit it to the Git repo.</p>
|
||||
|
||||
<h3><a name="Machi_Code_Overview">Machi Code Overview</a></h3>
|
||||
|
||||
<h4><a name="Chain_Manager">Chain Manager</a></h4>
|
||||
|
||||
<p>The Chain Manager is responsible for managing the state of Machi's
|
||||
"Chain Replication" state. This role is roughly analogous to the
|
||||
"Riak Core" application inside of Riak, which takes care of
|
||||
coordinating replica placement and replica repair.</p>
|
||||
|
||||
<p>For each primitive data server in the cluster, a Machi FLU, there is a
|
||||
Chain Manager process that manages its FLU's role within the Machi
|
||||
cluster's Chain Replication scheme. Each Chain Manager process
|
||||
executes locally and independently to manage the distributed state of
|
||||
a single Machi Chain Replication chain.</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li><p> To contrast with Riak Core ... Riak Core's claimant process is
|
||||
solely responsible for managing certain critical aspects of
|
||||
Riak Core distributed state. Machi's Chain Manager process
|
||||
performs similar tasks as Riak Core's claimant. However, Machi
|
||||
has several active Chain Manager processes, one per FLU server,
|
||||
instead of a single active process like Core's claimant. Each
|
||||
Chain Manager process acts independently; each is constrained
|
||||
so that it will reach consensus via independent computation
|
||||
& action.</p>
|
||||
|
||||
Full discussion of this distributed consensus is outside the
|
||||
scope of this document; see the "Pointers to Other Machi
|
||||
Documentation" section below for more information.
|
||||
</li>
|
||||
<li> Machi differs from a Riak Core application because Machi's
|
||||
replica placement policy is simply, "All Machi servers store
|
||||
replicas of all Machi files".
|
||||
Machi is intended to be a primitive building block for creating larger
|
||||
cluster-of-clusters where files are
|
||||
distributed/fragmented/sharded across a large pool of
|
||||
independent Machi clusters.
|
||||
</li>
|
||||
<li> See
|
||||
<a href="https://www.usenix.org/legacy/events/osdi04/tech/renesse.html" target="_top"><tt>https://www.usenix.org/legacy/events/osdi04/tech/renesse.html</tt></a>
|
||||
for a copy of the paper, "Chain Replication for Supporting High
|
||||
Throughput and Availability" by Robbert van Renesse and Fred
|
||||
B. Schneider.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4><a name="FLU">FLU</a></h4>
|
||||
|
||||
<p>The FLU is the basic storage server for Machi.</p>
|
||||
|
||||
<ul>
|
||||
<li> The name FLU is taken from "flash storage unit" from the paper
|
||||
"CORFU: A Shared Log Design for Flash Clusters" by
|
||||
Balakrishnan, Malkhi, Prabhakaran, and Wobber. See
|
||||
<a href="https://www.usenix.org/conference/nsdi12/technical-sessions/presentation/balakrishnan" target="_top"><tt>https://www.usenix.org/conference/nsdi12/technical-sessions/presentation/balakrishnan</tt></a>
|
||||
</li>
|
||||
<li> In CORFU, the sequencer step is a prerequisite step that is
|
||||
performed by a separate component, the Sequencer.
|
||||
In Machi, the <code>append_chunk()</code> protocol message has
|
||||
an implicit "sequencer" operation applied by the "head" of the
|
||||
Machi Chain Replication chain. If a client wishes to write
|
||||
data that has already been assigned a sequencer position, then
|
||||
the <code>write_chunk()</code> API function is used.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>For each FLU, there are three independent tasks that are implemented
|
||||
using three different Erlang processes:</p>
|
||||
|
||||
<ul>
|
||||
<li> A FLU server, implemented primarily by <code>machi_flu.erl</code>.
|
||||
</li>
|
||||
<li> A projection store server, implemented primarily by
|
||||
<code>machi_projection_store.erl</code>.
|
||||
</li>
|
||||
<li> A chain state manager server, implemented primarily by
|
||||
<code>machi_chain_manager1.erl</code>.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>From the perspective of failure detection, it is very convenient that
|
||||
all three FLU-related services (file server, sequencer server, and
|
||||
projection server) are accessed using the same single TCP port.</p>
|
||||
|
||||
<h4><a name="Projection_(data_structure)">Projection (data structure)</a></h4>
|
||||
|
||||
<p>The projection is a data structure that specifies the current state
|
||||
of the Machi cluster: all FLUs, which FLUS are considered
|
||||
up/running or down/crashed/stopped, which FLUs are actively
|
||||
participants in the Chain Replication protocol, and which FLUs are
|
||||
under "repair" (i.e., having their data resyncronized when
|
||||
newly-added to a cluster or when restarting after a crash).</p>
|
||||
|
||||
<h4><a name="Projection_Store_(server)">Projection Store (server)</a></h4>
|
||||
|
||||
<p>The projection store is a storage service that is implemented by an
|
||||
Erlang/OTP <code>gen_server</code> process that is associated with each
|
||||
FLU. Conceptually, the projection store is an array of
|
||||
write-once registers. For each projection store register, the
|
||||
key is a 2-tuple of an epoch number (<code>non_neg_integer()</code> type)
|
||||
and a projection type (<code>public</code> or <code>private</code> type); the value is
|
||||
a projection data structure (<code>projection_v1()</code> type).</p>
|
||||
|
||||
<h4><a name="Client_and_Proxy_Client">Client and Proxy Client</a></h4>
|
||||
|
||||
<p>Machi is intentionally avoiding using distributed Erlang for Machi's
|
||||
communication. This design decision makes Erlang-side code more
|
||||
difficult & complex but allows us the freedom of implementing
|
||||
parts of Machi in other languages without major
|
||||
protocol&API&glue code changes later in the product's
|
||||
lifetime.</p>
|
||||
|
||||
<p>There are two layers of interface for Machi clients.</p>
|
||||
|
||||
<ul>
|
||||
<li> The <code>machi_flu1_client</code> module implements an API that uses a
|
||||
TCP socket directly.
|
||||
</li>
|
||||
<li> The <code>machi_proxy_flu1_client</code> module implements an API that
|
||||
uses a local, long-lived <code>gen_server</code> process as a proxy for
|
||||
the remote, perhaps disconnected-or-crashed Machi FLU server.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>The types for both modules ought to be the same. However, due to
|
||||
rapid code churn, some differences might exist. Any major difference
|
||||
is (almost by definition) a bug: please open a GitHub issue to request
|
||||
a correction.</p>
|
||||
|
||||
<h3><a name="TODO_notes">TODO notes</a></h3>
|
||||
|
||||
<p>Any use of the string "TODO" in upper/lower/mixed case, anywhere in
|
||||
the code, is a reminder signal of unfinished work.</p>
|
||||
|
||||
<h3><a name="Pointers_to_Other_Machi_Documentation">Pointers to Other Machi Documentation</a></h3>
|
||||
|
||||
<ul>
|
||||
<li> If you are viewing this document locally, please look in the
|
||||
<code>../doc/</code> directory,
|
||||
</li>
|
||||
<li> If you are viewing this document via the Web, please find the
|
||||
documentation via this link:
|
||||
<a href="http://github.com/basho/machi/tree/master/doc/" target="_top"><tt>http://github.com/basho/machi/tree/master/doc/</tt></a>
|
||||
Please be aware that this link points to the <code>master</code> branch
|
||||
of the Machi source repository and therefore may be
|
||||
out-of-sync with non-<code>master</code> branch code.
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div>
|
||||
<p><i>Generated by EDoc, Apr 8 2015, 17:31:11.</i></p>
|
||||
</body>
|
||||
</html>
|
14
edoc/overview.edoc
Normal file
14
edoc/overview.edoc
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
@title Machi: a small village of replicated files
|
||||
|
||||
@doc
|
||||
|
||||
Documentation for Machi is an ongoing challenge. Much of the
|
||||
high-level design & commentary are outside of the Erlang EDoc system
|
||||
|
||||
Zoom2 zoom zoom zoom boom boom boom boom
|
||||
|
||||
Rumba tango Rumba tango Rumba tango Rumba tango Rumba tango Rumba
|
||||
tango Rumba tango Rumba tango Rumba tango Rumba tango Rumba tango
|
||||
Rumba tango Rumba tango Rumba tango Rumba tango Rumba tango Rumba
|
||||
tango Rumba tango Rumba tango Rumba tango Rumba tango
|
11
edoc/packages-frame.html
Normal file
11
edoc/packages-frame.html
Normal file
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>The machi application</title>
|
||||
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<h2 class="indextitle">Packages</h2>
|
||||
<table width="100%" border="0" summary="list of packages"></table>
|
||||
</body>
|
||||
</html>
|
55
edoc/stylesheet.css
Normal file
55
edoc/stylesheet.css
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* standard EDoc style sheet */
|
||||
body {
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
margin-left: .25in;
|
||||
margin-right: .2in;
|
||||
margin-top: 0.2in;
|
||||
margin-bottom: 0.2in;
|
||||
color: #000000;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
h1,h2 {
|
||||
margin-left: -0.2in;
|
||||
}
|
||||
div.navbar {
|
||||
background-color: #add8e6;
|
||||
padding: 0.2em;
|
||||
}
|
||||
h2.indextitle {
|
||||
padding: 0.4em;
|
||||
background-color: #add8e6;
|
||||
}
|
||||
h3.function,h3.typedecl {
|
||||
background-color: #add8e6;
|
||||
padding-left: 1em;
|
||||
}
|
||||
div.spec {
|
||||
margin-left: 2em;
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
a.module,a.package {
|
||||
text-decoration:none
|
||||
}
|
||||
a.module:hover,a.package:hover {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
ul.definitions {
|
||||
list-style-type: none;
|
||||
}
|
||||
ul.index {
|
||||
list-style-type: none;
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
|
||||
/*
|
||||
* Minor style tweaks
|
||||
*/
|
||||
ul {
|
||||
list-style-type: square;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
td {
|
||||
padding: 3
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
%%% {erl_opts, [warnings_as_errors, {parse_transform, lager_transform}, debug_info]}.
|
||||
{erl_opts, [{parse_transform, lager_transform}, debug_info]}.
|
||||
{edoc_opts, [{dir, "./edoc"}]}.
|
||||
|
||||
{deps, [
|
||||
{lager, ".*", {git, "git://github.com/basho/lager.git", {tag, "2.0.1"}}}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
%%
|
||||
%% -------------------------------------------------------------------
|
||||
|
||||
%% @doc Machi chain replication administration utilities.
|
||||
|
||||
-module(machi_admin_util).
|
||||
|
||||
%% TODO Move these types to a common header file? (also machi_flu1_client.erl?)
|
||||
|
@ -114,7 +116,7 @@ verify_chunk_checksum(File, ReadChunk) ->
|
|||
fun({Offset, Size, CSum}, Acc) ->
|
||||
case ReadChunk(File, Offset, Size) of
|
||||
{ok, Chunk} ->
|
||||
CSum2 = machi_util:checksum(Chunk),
|
||||
CSum2 = machi_util:checksum_chunk(Chunk),
|
||||
if CSum == CSum2 ->
|
||||
Acc;
|
||||
true ->
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
%%
|
||||
%% -------------------------------------------------------------------
|
||||
|
||||
%% @doc Top-level supervisor for the Machi application.
|
||||
|
||||
-module(machi_app).
|
||||
|
||||
-behaviour(application).
|
||||
|
|
|
@ -19,6 +19,28 @@
|
|||
%% under the License.
|
||||
%%
|
||||
%% -------------------------------------------------------------------
|
||||
|
||||
%% @doc The Machi chain manager, Guardian of all things related to
|
||||
%% Chain Replication state, status, and data replica safety.
|
||||
%%
|
||||
%% The Chain Manager is responsible for managing the state of Machi's
|
||||
%% "Chain Replication" state. This role is roughly analogous to the
|
||||
%% "Riak Core" application inside of Riak, which takes care of
|
||||
%% coordinating replica placement and replica repair.
|
||||
%%
|
||||
%% For each primitive data server in the cluster, a Machi FLU, there
|
||||
%% is a Chain Manager process that manages its FLU's role within the
|
||||
%% Machi cluster's Chain Replication scheme. Each Chain Manager
|
||||
%% process executes locally and independently to manage the
|
||||
%% distributed state of a single Machi Chain Replication chain.
|
||||
%%
|
||||
%% Machi's Chain Manager process performs similar tasks as Riak Core's
|
||||
%% claimant. However, Machi has several active Chain Manager
|
||||
%% processes, one per FLU server, instead of a single active process
|
||||
%% like Core's claimant. Each Chain Manager process acts
|
||||
%% independently; each is constrained so that it will reach consensus
|
||||
%% via independent computation & action.
|
||||
|
||||
-module(machi_chain_manager1).
|
||||
|
||||
%% TODO: I am going to sever the connection between the flowchart and the
|
||||
|
|
|
@ -16,9 +16,13 @@
|
|||
%%%
|
||||
%%%-------------------------------------------------------------------
|
||||
|
||||
%% Consistent hashing library. Also known as "random slicing".
|
||||
%% Originally from the Hibari DB source code at https://github.com/hibari
|
||||
%% @doc Consistent hashing library. Also known as "random slicing".
|
||||
%%
|
||||
%% This code was originally from the Hibari DB source code at
|
||||
%% [https://github.com/hibari]
|
||||
|
||||
-module(machi_chash).
|
||||
|
||||
%% TODO items:
|
||||
%%
|
||||
%% 1. Refactor to use bigints instead of floating point numbers. The
|
||||
|
@ -26,8 +30,6 @@
|
|||
%% much wiggle-room for making really small hashing range
|
||||
%% definitions.
|
||||
|
||||
-module(machi_chash).
|
||||
|
||||
-define(SMALLEST_SIGNIFICANT_FLOAT_SIZE, 0.1e-12).
|
||||
-define(SHA_MAX, (1 bsl (20*8))).
|
||||
|
||||
|
|
|
@ -18,6 +18,33 @@
|
|||
%%
|
||||
%% -------------------------------------------------------------------
|
||||
|
||||
%% @doc The Machi FLU file server + file location sequencer.
|
||||
%%
|
||||
%% This module implements only the Machi FLU file server and its
|
||||
%% implicit sequencer.
|
||||
%% Please see the EDoc "Overview" for details about the FLU as a
|
||||
%% primitive file server process vs. the larger Machi design of a FLU
|
||||
%% as a sequencer + file server + chain manager group of processes.
|
||||
%%
|
||||
%% For the moment, this module also implements a rudimentary TCP-based
|
||||
%% protocol as the sole supported access method to the server,
|
||||
%% sequencer, and projection store. Conceptually, those three
|
||||
%% services are independent and ought to have their own protocols. As
|
||||
%% a practical matter, there is no need for wire protocol
|
||||
%% compatibility. Furthermore, from the perspective of failure
|
||||
%% detection, it is very convenient that all three FLU-related
|
||||
%% services are accessed using the same single TCP port.
|
||||
%%
|
||||
%% The FLU is named after the CORFU server "FLU" or "FLash Unit" server.
|
||||
%%
|
||||
%% TODO There is one major missing feature in this FLU implementation:
|
||||
%% there is no "write-once" enforcement for any position in a Machi
|
||||
%% file. At the moment, we rely on correct behavior of the client
|
||||
%% & the sequencer to avoid overwriting data. In the Real World,
|
||||
%% however, all Machi file data is supposed to be exactly write-once
|
||||
%% to avoid problems with bugs, wire protocol corruption, malicious
|
||||
%% clients, etc.
|
||||
|
||||
-module(machi_flu1).
|
||||
|
||||
-include_lib("kernel/include/file.hrl").
|
||||
|
@ -218,7 +245,7 @@ do_net_server_append2(RegName, Sock, LenHex, Prefix) ->
|
|||
<<Len:32/big>> = machi_util:hexstr_to_bin(LenHex),
|
||||
ok = inet:setopts(Sock, [{packet, raw}]),
|
||||
{ok, Chunk} = gen_tcp:recv(Sock, Len, 60*1000),
|
||||
CSum = machi_util:checksum(Chunk),
|
||||
CSum = machi_util:checksum_chunk(Chunk),
|
||||
try
|
||||
RegName ! {seq_append, self(), Prefix, Chunk, CSum}
|
||||
catch error:badarg ->
|
||||
|
@ -300,7 +327,7 @@ do_net_server_write2(Sock, OffsetHex, LenHex, FileBin, DataDir, FHc) ->
|
|||
DoItFun = fun(FHd, Offset, Len) ->
|
||||
ok = inet:setopts(Sock, [{packet, raw}]),
|
||||
{ok, Chunk} = gen_tcp:recv(Sock, Len),
|
||||
CSum = machi_util:checksum(Chunk),
|
||||
CSum = machi_util:checksum_chunk(Chunk),
|
||||
case file:pwrite(FHd, Offset, Chunk) of
|
||||
ok ->
|
||||
CSumHex = machi_util:bin_to_hexstr(CSum),
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
%%
|
||||
%% -------------------------------------------------------------------
|
||||
|
||||
%% @doc Erlang API for the Machi FLU TCP protocol version 1.
|
||||
|
||||
-module(machi_flu1_client).
|
||||
|
||||
-include("machi.hrl").
|
||||
|
@ -151,7 +153,7 @@ list_files(Host, TcpPort, EpochID) when is_integer(TcpPort) ->
|
|||
catch gen_tcp:close(Sock)
|
||||
end.
|
||||
|
||||
%% @doc Get the latest epoch number from the FLU's projection store.
|
||||
%% @doc Get the latest epoch number + checksum from the FLU's projection store.
|
||||
|
||||
-spec get_latest_epoch(port(), projection_type()) ->
|
||||
{ok, epoch_id()} | {error, term()}.
|
||||
|
@ -159,7 +161,7 @@ get_latest_epoch(Sock, ProjType)
|
|||
when ProjType == 'public' orelse ProjType == 'private' ->
|
||||
get_latest_epoch2(Sock, ProjType).
|
||||
|
||||
%% @doc Get the latest epoch number from the FLU's projection store.
|
||||
%% @doc Get the latest epoch number + checksum from the FLU's projection store.
|
||||
|
||||
-spec get_latest_epoch(inet_host(), inet_port(),
|
||||
projection_type()) ->
|
||||
|
@ -173,7 +175,7 @@ get_latest_epoch(Host, TcpPort, ProjType)
|
|||
catch gen_tcp:close(Sock)
|
||||
end.
|
||||
|
||||
%% @doc Get the latest epoch number from the FLU's projection store.
|
||||
%% @doc Get the latest projection from the FLU's projection store for `ProjType'
|
||||
|
||||
-spec read_latest_projection(port(), projection_type()) ->
|
||||
{ok, projection()} | {error, not_written} | {error, term()}.
|
||||
|
@ -181,7 +183,7 @@ read_latest_projection(Sock, ProjType)
|
|||
when ProjType == 'public' orelse ProjType == 'private' ->
|
||||
read_latest_projection2(Sock, ProjType).
|
||||
|
||||
%% @doc Get the latest epoch number from the FLU's projection store.
|
||||
%% @doc Get the latest projection from the FLU's projection store for `ProjType'
|
||||
|
||||
-spec read_latest_projection(inet_host(), inet_port(),
|
||||
projection_type()) ->
|
||||
|
@ -368,7 +370,7 @@ append_chunk2(Sock, EpochID, Prefix0, Chunk0) ->
|
|||
erase(bad_sock),
|
||||
try
|
||||
%% TODO: add client-side checksum to the server's protocol
|
||||
%% _ = crypto:hash(md5, Chunk),
|
||||
%% _ = machi_util:checksum_chunk(Chunk),
|
||||
Prefix = machi_util:make_binary(Prefix0),
|
||||
Chunk = machi_util:make_binary(Chunk0),
|
||||
Len = iolist_size(Chunk0),
|
||||
|
@ -536,7 +538,7 @@ write_chunk2(Sock, EpochID, File0, Offset, Chunk0) ->
|
|||
{EpochNum, EpochCSum} = EpochID,
|
||||
EpochIDRaw = <<EpochNum:(4*8)/big, EpochCSum/binary>>,
|
||||
%% TODO: add client-side checksum to the server's protocol
|
||||
%% _ = crypto:hash(md5, Chunk),
|
||||
%% _ = machi_util:checksum_chunk(Chunk),
|
||||
File = machi_util:make_binary(File0),
|
||||
true = (Offset >= ?MINIMUM_OFFSET),
|
||||
OffsetHex = machi_util:int_to_hexbin(Offset, 64),
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
%%
|
||||
%% -------------------------------------------------------------------
|
||||
|
||||
%% @doc Supervisor for Machi FLU servers and their related support
|
||||
%% servers.
|
||||
|
||||
-module(machi_flu_sup).
|
||||
|
||||
-behaviour(supervisor).
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
%%
|
||||
%% -------------------------------------------------------------------
|
||||
|
||||
%% @doc API for manipulating Machi projection data structures (i.e., records).
|
||||
|
||||
-module(machi_projection).
|
||||
|
||||
-include("machi_projection.hrl").
|
||||
|
@ -30,13 +32,19 @@
|
|||
make_projection_summary/1
|
||||
]).
|
||||
|
||||
%% @doc Create a new projection record.
|
||||
|
||||
new(MyName, All_list, UPI_list, Down_list, Repairing_list, Ps) ->
|
||||
new(0, MyName, All_list, Down_list, UPI_list, Repairing_list, Ps).
|
||||
|
||||
%% @doc Create a new projection record.
|
||||
|
||||
new(EpochNum, MyName, All_list, Down_list, UPI_list, Repairing_list, Dbg) ->
|
||||
new(EpochNum, MyName, All_list, Down_list, UPI_list, Repairing_list,
|
||||
Dbg, []).
|
||||
|
||||
%% @doc Create a new projection record.
|
||||
|
||||
new(EpochNum, MyName, All_list0, Down_list, UPI_list, Repairing_list,
|
||||
Dbg, Dbg2)
|
||||
when is_integer(EpochNum), EpochNum >= 0,
|
||||
|
@ -87,15 +95,22 @@ new(EpochNum, MyName, All_list0, Down_list, UPI_list, Repairing_list,
|
|||
},
|
||||
update_projection_dbg2(update_projection_checksum(P), Dbg2).
|
||||
|
||||
%% @doc Update the checksum element of a projection record.
|
||||
|
||||
update_projection_checksum(P) ->
|
||||
CSum = crypto:hash(sha,
|
||||
term_to_binary(P#projection_v1{epoch_csum= <<>>,
|
||||
dbg2=[]})),
|
||||
P#projection_v1{epoch_csum=CSum}.
|
||||
|
||||
%% @doc Update the `dbg2' element of a projection record.
|
||||
|
||||
update_projection_dbg2(P, Dbg2) when is_list(Dbg2) ->
|
||||
P#projection_v1{dbg2=Dbg2}.
|
||||
|
||||
%% @doc Compare two projection records for equality (assuming that the
|
||||
%% checksum element has been correctly calculated).
|
||||
|
||||
-spec compare(#projection_v1{}, #projection_v1{}) ->
|
||||
integer().
|
||||
compare(#projection_v1{epoch_number=E1, epoch_csum=C1},
|
||||
|
@ -107,6 +122,8 @@ compare(#projection_v1{epoch_number=E1},
|
|||
E1 > E2 -> 1
|
||||
end.
|
||||
|
||||
%% @doc Create a proplist-style summary of a projection record.
|
||||
|
||||
make_projection_summary(#projection_v1{epoch_number=EpochNum,
|
||||
all_members=_All_list,
|
||||
down=Down_list,
|
||||
|
|
|
@ -18,6 +18,25 @@
|
|||
%%
|
||||
%% -------------------------------------------------------------------
|
||||
|
||||
%% @doc The Machi write-once projection store service.
|
||||
%%
|
||||
%% This API is gen_server-style message passing, intended for use
|
||||
%% within a single Erlang node to glue together the projection store
|
||||
%% server with the node-local process that implements Machi's TCP
|
||||
%% client access protocol (on the "server side" of the TCP connection).
|
||||
%%
|
||||
%% All Machi client access to the projection store SHOULD NOT use this
|
||||
%% module's API.
|
||||
%%
|
||||
%% The projection store is implemented by an Erlang/OTP `gen_server'
|
||||
%% process that is associated with each FLU. Conceptually, the
|
||||
%% projection store is an array of write-once registers. For each
|
||||
%% projection store register, the key is a 2-tuple of an epoch number
|
||||
%% (`non_neg_integer()' type) and a projection type (`public' or
|
||||
%% `private' type); the value is a projection data structure
|
||||
%% (`projection_v1()' type).
|
||||
|
||||
|
||||
-module(machi_projection_store).
|
||||
|
||||
-include("machi_projection.hrl").
|
||||
|
@ -48,35 +67,60 @@
|
|||
max_private_epoch = ?NO_EPOCH :: {-1 | non_neg_integer(), binary()}
|
||||
}).
|
||||
|
||||
%% @doc Start a new projection store server.
|
||||
%%
|
||||
%% The `DataDir' argument should be the same directory as specified
|
||||
%% for use by our companion FLU data server -- all file system paths
|
||||
%% used by this server are intended to be stored underneath a common
|
||||
%% file system parent directory as the FLU data server & sequencer
|
||||
%% servers.
|
||||
|
||||
start_link(RegName, DataDir, NotifyWedgeStateChanges) ->
|
||||
gen_server:start_link({local, RegName},
|
||||
?MODULE, [DataDir, NotifyWedgeStateChanges], []).
|
||||
|
||||
%% @doc Fetch the latest epoch number + checksum for type `ProjType'.
|
||||
|
||||
get_latest_epoch(PidSpec, ProjType) ->
|
||||
get_latest_epoch(PidSpec, ProjType, infinity).
|
||||
|
||||
%% @doc Fetch the latest epoch number + checksum for type `ProjType'.
|
||||
%% projection.
|
||||
|
||||
get_latest_epoch(PidSpec, ProjType, Timeout)
|
||||
when ProjType == 'public' orelse ProjType == 'private' ->
|
||||
g_call(PidSpec, {get_latest_epoch, ProjType}, Timeout).
|
||||
|
||||
%% @doc Fetch the latest projection record for type `ProjType'.
|
||||
|
||||
read_latest_projection(PidSpec, ProjType) ->
|
||||
read_latest_projection(PidSpec, ProjType, infinity).
|
||||
|
||||
%% @doc Fetch the latest projection record for type `ProjType'.
|
||||
|
||||
read_latest_projection(PidSpec, ProjType, Timeout)
|
||||
when ProjType == 'public' orelse ProjType == 'private' ->
|
||||
g_call(PidSpec, {read_latest_projection, ProjType}, Timeout).
|
||||
|
||||
%% @doc Fetch the projection record type `ProjType' for epoch number `Epoch' .
|
||||
|
||||
read(PidSpec, ProjType, Epoch) ->
|
||||
read(PidSpec, ProjType, Epoch, infinity).
|
||||
|
||||
%% @doc Fetch the projection record type `ProjType' for epoch number `Epoch' .
|
||||
|
||||
read(PidSpec, ProjType, Epoch, Timeout)
|
||||
when ProjType == 'public' orelse ProjType == 'private',
|
||||
is_integer(Epoch), Epoch >= 0 ->
|
||||
g_call(PidSpec, {read, ProjType, Epoch}, Timeout).
|
||||
|
||||
%% @doc Write the projection record type `ProjType' for epoch number `Epoch' .
|
||||
|
||||
write(PidSpec, ProjType, Proj) ->
|
||||
write(PidSpec, ProjType, Proj, infinity).
|
||||
|
||||
%% @doc Write the projection record type `ProjType' for epoch number `Epoch' .
|
||||
|
||||
write(PidSpec, ProjType, Proj, Timeout)
|
||||
when ProjType == 'public' orelse ProjType == 'private',
|
||||
is_record(Proj, projection_v1),
|
||||
|
@ -84,16 +128,24 @@ write(PidSpec, ProjType, Proj, Timeout)
|
|||
Proj#projection_v1.epoch_number >= 0 ->
|
||||
g_call(PidSpec, {write, ProjType, Proj}, Timeout).
|
||||
|
||||
%% @doc Fetch all projection records of type `ProjType'.
|
||||
|
||||
get_all_projections(PidSpec, ProjType) ->
|
||||
get_all_projections(PidSpec, ProjType, infinity).
|
||||
|
||||
%% @doc Fetch all projection records of type `ProjType'.
|
||||
|
||||
get_all_projections(PidSpec, ProjType, Timeout)
|
||||
when ProjType == 'public' orelse ProjType == 'private' ->
|
||||
g_call(PidSpec, {get_all_projections, ProjType}, Timeout).
|
||||
|
||||
%% @doc Fetch all projection epoch numbers of type `ProjType'.
|
||||
|
||||
list_all_projections(PidSpec, ProjType) ->
|
||||
list_all_projections(PidSpec, ProjType, infinity).
|
||||
|
||||
%% @doc Fetch all projection epoch numbers of type `ProjType'.
|
||||
|
||||
list_all_projections(PidSpec, ProjType, Timeout)
|
||||
when ProjType == 'public' orelse ProjType == 'private' ->
|
||||
g_call(PidSpec, {list_all_projections, ProjType}, Timeout).
|
||||
|
|
|
@ -18,6 +18,23 @@
|
|||
%%
|
||||
%% -------------------------------------------------------------------
|
||||
|
||||
%% @doc Erlang API for the Machi FLU TCP protocol version 1, with a
|
||||
%% proxy-process style API for hiding messy details such as TCP
|
||||
%% connection/disconnection with the remote Machi server.
|
||||
%%
|
||||
%% Machi is intentionally avoiding using distributed Erlang for
|
||||
%% Machi's communication. This design decision makes Erlang-side code
|
||||
%% more difficult & complex, but it's the price to pay for some
|
||||
%% language independence. Later in Machi's life cycle, we need to
|
||||
%% (re-)implement some components in a non-Erlang/BEAM-based language.
|
||||
%%
|
||||
%% This module implements a "man in the middle" proxy between the
|
||||
%% Erlang client and Machi server (which is on the "far side" of a TCP
|
||||
%% connection to somewhere). This proxy process will always execute
|
||||
%% on the same Erlang node as the Erlang client that uses it. The
|
||||
%% proxy is intended to be a stable, long-lived process that survives
|
||||
%% TCP communication problems with the remote server.
|
||||
|
||||
-module(machi_proxy_flu1_client).
|
||||
|
||||
-behaviour(gen_server).
|
||||
|
@ -61,79 +78,128 @@
|
|||
sock :: 'undefined' | port()
|
||||
}).
|
||||
|
||||
%% @doc Start a local, long-lived process that will be our steady
|
||||
%% & reliable communication proxy with the fickle & flaky
|
||||
%% remote Machi server.
|
||||
|
||||
start_link(#p_srvr{}=I) ->
|
||||
gen_server:start_link(?MODULE, [I], []).
|
||||
|
||||
%% @doc Append a chunk (binary- or iolist-style) of data to a file
|
||||
%% with `Prefix'.
|
||||
|
||||
append_chunk(PidSpec, EpochID, Prefix, Chunk) ->
|
||||
append_chunk(PidSpec, EpochID, Prefix, Chunk, infinity).
|
||||
|
||||
%% @doc Append a chunk (binary- or iolist-style) of data to a file
|
||||
%% with `Prefix'.
|
||||
|
||||
append_chunk(PidSpec, EpochID, Prefix, Chunk, Timeout) ->
|
||||
gen_server:call(PidSpec, {req, {append_chunk, EpochID, Prefix, Chunk}},
|
||||
Timeout).
|
||||
|
||||
%% @doc Read a chunk of data of size `Size' from `File' at `Offset'.
|
||||
|
||||
read_chunk(PidSpec, EpochID, File, Offset, Size) ->
|
||||
read_chunk(PidSpec, EpochID, File, Offset, Size, infinity).
|
||||
|
||||
%% @doc Read a chunk of data of size `Size' from `File' at `Offset'.
|
||||
|
||||
read_chunk(PidSpec, EpochID, File, Offset, Size, Timeout) ->
|
||||
gen_server:call(PidSpec, {req, {read_chunk, EpochID, File, Offset, Size}},
|
||||
Timeout).
|
||||
|
||||
%% @doc Fetch the list of chunk checksums for `File'.
|
||||
|
||||
checksum_list(PidSpec, EpochID, File) ->
|
||||
checksum_list(PidSpec, EpochID, File, infinity).
|
||||
|
||||
%% @doc Fetch the list of chunk checksums for `File'.
|
||||
|
||||
checksum_list(PidSpec, EpochID, File, Timeout) ->
|
||||
gen_server:call(PidSpec, {req, {checksum_list, EpochID, File}},
|
||||
Timeout).
|
||||
|
||||
%% @doc Fetch the list of all files on the remote FLU.
|
||||
|
||||
list_files(PidSpec, EpochID) ->
|
||||
list_files(PidSpec, EpochID, infinity).
|
||||
|
||||
%% @doc Fetch the list of all files on the remote FLU.
|
||||
|
||||
list_files(PidSpec, EpochID, Timeout) ->
|
||||
gen_server:call(PidSpec, {req, {list_files, EpochID}},
|
||||
Timeout).
|
||||
|
||||
%% @doc Get the latest epoch number + checksum from the FLU's projection store.
|
||||
|
||||
get_latest_epoch(PidSpec, ProjType) ->
|
||||
get_latest_epoch(PidSpec, ProjType, infinity).
|
||||
|
||||
%% @doc Get the latest epoch number + checksum from the FLU's projection store.
|
||||
|
||||
get_latest_epoch(PidSpec, ProjType, Timeout) ->
|
||||
gen_server:call(PidSpec, {req, {get_latest_epoch, ProjType}},
|
||||
Timeout).
|
||||
|
||||
%% @doc Get the latest projection from the FLU's projection store for `ProjType'
|
||||
|
||||
read_latest_projection(PidSpec, ProjType) ->
|
||||
read_latest_projection(PidSpec, ProjType, infinity).
|
||||
|
||||
%% @doc Get the latest projection from the FLU's projection store for `ProjType'
|
||||
|
||||
read_latest_projection(PidSpec, ProjType, Timeout) ->
|
||||
gen_server:call(PidSpec, {req, {read_latest_projection, ProjType}},
|
||||
Timeout).
|
||||
|
||||
%% @doc Read a projection `Proj' of type `ProjType'.
|
||||
|
||||
read_projection(PidSpec, ProjType, Epoch) ->
|
||||
read_projection(PidSpec, ProjType, Epoch, infinity).
|
||||
|
||||
%% @doc Read a projection `Proj' of type `ProjType'.
|
||||
|
||||
read_projection(PidSpec, ProjType, Epoch, Timeout) ->
|
||||
gen_server:call(PidSpec, {req, {read_projection, ProjType, Epoch}},
|
||||
Timeout).
|
||||
|
||||
%% @doc Write a projection `Proj' of type `ProjType'.
|
||||
|
||||
write_projection(PidSpec, ProjType, Proj) ->
|
||||
write_projection(PidSpec, ProjType, Proj, infinity).
|
||||
|
||||
%% @doc Write a projection `Proj' of type `ProjType'.
|
||||
|
||||
write_projection(PidSpec, ProjType, Proj, Timeout) ->
|
||||
gen_server:call(PidSpec, {req, {write_projection, ProjType, Proj}},
|
||||
Timeout).
|
||||
|
||||
%% @doc Get all projections from the FLU's projection store.
|
||||
|
||||
get_all_projections(PidSpec, ProjType) ->
|
||||
get_all_projections(PidSpec, ProjType, infinity).
|
||||
|
||||
%% @doc Get all projections from the FLU's projection store.
|
||||
|
||||
get_all_projections(PidSpec, ProjType, Timeout) ->
|
||||
gen_server:call(PidSpec, {req, {get_all_projections, ProjType}},
|
||||
Timeout).
|
||||
|
||||
%% @doc Get all epoch numbers from the FLU's projection store.
|
||||
|
||||
list_all_projections(PidSpec, ProjType) ->
|
||||
list_all_projections(PidSpec, ProjType, infinity).
|
||||
|
||||
%% @doc Get all epoch numbers from the FLU's projection store.
|
||||
|
||||
list_all_projections(PidSpec, ProjType, Timeout) ->
|
||||
gen_server:call(PidSpec, {req, {list_all_projections, ProjType}},
|
||||
Timeout).
|
||||
|
||||
%% @doc Quit & close the connection to remote FLU and stop our
|
||||
%% proxy process.
|
||||
|
||||
quit(PidSpec) ->
|
||||
gen_server:call(PidSpec, quit, infinity).
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
%%
|
||||
%% -------------------------------------------------------------------
|
||||
|
||||
%% @doc "Mothballed" sequencer code, perhaps to be reused sometime in
|
||||
%% the future?
|
||||
|
||||
-module(machi_sequencer).
|
||||
|
||||
-compile(export_all).
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
%%
|
||||
%% -------------------------------------------------------------------
|
||||
|
||||
%% @doc Top Machi application supervisor.
|
||||
|
||||
-module(machi_sup).
|
||||
|
||||
-behaviour(supervisor).
|
||||
|
|
|
@ -18,10 +18,12 @@
|
|||
%%
|
||||
%% -------------------------------------------------------------------
|
||||
|
||||
%% @doc Miscellaneous utility functions.
|
||||
|
||||
-module(machi_util).
|
||||
|
||||
-export([
|
||||
checksum/1,
|
||||
checksum_chunk/1,
|
||||
hexstr_to_bin/1, bin_to_hexstr/1,
|
||||
hexstr_to_int/1, int_to_hexstr/2, int_to_hexbin/2,
|
||||
make_binary/1, make_string/1,
|
||||
|
@ -39,33 +41,34 @@
|
|||
-include("machi_projection.hrl").
|
||||
-include_lib("kernel/include/file.hrl").
|
||||
|
||||
append(Server, Prefix, Chunk) when is_binary(Prefix), is_binary(Chunk) ->
|
||||
CSum = checksum(Chunk),
|
||||
Server ! {seq_append, self(), Prefix, Chunk, CSum},
|
||||
receive
|
||||
{assignment, Offset, File} ->
|
||||
{Offset, File}
|
||||
after 10*1000 ->
|
||||
bummer
|
||||
end.
|
||||
%% @doc Create a registered name atom for FLU sequencer internal
|
||||
%% rendezvous/message passing use.
|
||||
|
||||
make_regname(Prefix) when is_binary(Prefix) ->
|
||||
erlang:binary_to_atom(Prefix, latin1);
|
||||
make_regname(Prefix) when is_list(Prefix) ->
|
||||
erlang:list_to_atom(Prefix).
|
||||
|
||||
%% @doc Calculate a config file path, by common convention.
|
||||
|
||||
make_config_filename(DataDir, Prefix) ->
|
||||
lists:flatten(io_lib:format("~s/config/~s", [DataDir, Prefix])).
|
||||
|
||||
%% @doc Calculate a checksum file path, by common convention.
|
||||
|
||||
make_checksum_filename(DataDir, Prefix, SequencerName, FileNum) ->
|
||||
lists:flatten(io_lib:format("~s/config/~s.~s.~w.csum",
|
||||
[DataDir, Prefix, SequencerName, FileNum])).
|
||||
|
||||
%% @doc Calculate a checksum file path, by common convention.
|
||||
|
||||
make_checksum_filename(DataDir, "") ->
|
||||
lists:flatten(io_lib:format("~s/config", [DataDir]));
|
||||
make_checksum_filename(DataDir, FileName) ->
|
||||
lists:flatten(io_lib:format("~s/config/~s.csum", [DataDir, FileName])).
|
||||
|
||||
%% @doc Calculate a file data file path, by common convention.
|
||||
|
||||
make_data_filename(DataDir, "") ->
|
||||
FullPath = lists:flatten(io_lib:format("~s/data", [DataDir])),
|
||||
{"", FullPath};
|
||||
|
@ -73,17 +76,24 @@ make_data_filename(DataDir, File) ->
|
|||
FullPath = lists:flatten(io_lib:format("~s/data/~s", [DataDir, File])),
|
||||
{File, FullPath}.
|
||||
|
||||
%% @doc Calculate a file data file path, by common convention.
|
||||
|
||||
make_data_filename(DataDir, Prefix, SequencerName, FileNum) ->
|
||||
File = erlang:iolist_to_binary(io_lib:format("~s.~s.~w",
|
||||
[Prefix, SequencerName, FileNum])),
|
||||
FullPath = lists:flatten(io_lib:format("~s/data/~s", [DataDir, File])),
|
||||
{File, FullPath}.
|
||||
|
||||
%% @doc Calculate a projection store file path, by common convention.
|
||||
|
||||
make_projection_filename(DataDir, "") ->
|
||||
lists:flatten(io_lib:format("~s/projection", [DataDir]));
|
||||
make_projection_filename(DataDir, File) ->
|
||||
lists:flatten(io_lib:format("~s/projection/~s", [DataDir, File])).
|
||||
|
||||
%% @doc Read the file size of a config file, which is used as the
|
||||
%% basis for a minimum sequence number.
|
||||
|
||||
read_max_filenum(DataDir, Prefix) ->
|
||||
case file:read_file_info(make_config_filename(DataDir, Prefix)) of
|
||||
{error, enoent} ->
|
||||
|
@ -92,6 +102,9 @@ read_max_filenum(DataDir, Prefix) ->
|
|||
FI#file_info.size
|
||||
end.
|
||||
|
||||
%% @doc Increase the file size of a config file, which is used as the
|
||||
%% basis for a minimum sequence number.
|
||||
|
||||
increment_max_filenum(DataDir, Prefix) ->
|
||||
try
|
||||
{ok, FH} = file:open(make_config_filename(DataDir, Prefix), [append]),
|
||||
|
@ -103,6 +116,8 @@ increment_max_filenum(DataDir, Prefix) ->
|
|||
{error, Error, erlang:get_stacktrace()}
|
||||
end.
|
||||
|
||||
%% @doc Convert a hexadecimal string to a `binary()'.
|
||||
|
||||
hexstr_to_bin(S) when is_list(S) ->
|
||||
hexstr_to_bin(S, []);
|
||||
hexstr_to_bin(B) when is_binary(B) ->
|
||||
|
@ -114,6 +129,8 @@ hexstr_to_bin([X,Y|T], Acc) ->
|
|||
{ok, [V], []} = io_lib:fread("~16u", [X,Y]),
|
||||
hexstr_to_bin(T, [V | Acc]).
|
||||
|
||||
%% @doc Convert a `binary()' to a hexadecimal string.
|
||||
|
||||
bin_to_hexstr(<<>>) ->
|
||||
[];
|
||||
bin_to_hexstr(<<X:4, Y:4, Rest/binary>>) ->
|
||||
|
@ -124,40 +141,60 @@ hex_digit(X) when X < 10 ->
|
|||
hex_digit(X) ->
|
||||
X - 10 + $a.
|
||||
|
||||
%% @doc Convert a compatible Erlang data type into a `binary()' equivalent.
|
||||
|
||||
make_binary(X) when is_binary(X) ->
|
||||
X;
|
||||
make_binary(X) when is_list(X) ->
|
||||
iolist_to_binary(X).
|
||||
|
||||
%% @doc Convert a compatible Erlang data type into a `string()' equivalent.
|
||||
|
||||
make_string(X) when is_list(X) ->
|
||||
lists:flatten(X);
|
||||
make_string(X) when is_binary(X) ->
|
||||
binary_to_list(X).
|
||||
|
||||
%% @doc Convert a hexadecimal string to an integer.
|
||||
|
||||
hexstr_to_int(X) ->
|
||||
B = hexstr_to_bin(X),
|
||||
B_size = byte_size(B) * 8,
|
||||
<<I:B_size/big>> = B,
|
||||
I.
|
||||
|
||||
%% @doc Convert an integer into a hexadecimal string whose length is
|
||||
%% based on `I_size'.
|
||||
|
||||
int_to_hexstr(I, I_size) ->
|
||||
bin_to_hexstr(<<I:I_size/big>>).
|
||||
|
||||
%% @doc Convert an integer into a hexadecimal string (in `binary()'
|
||||
%% form) whose length is based on `I_size'.
|
||||
|
||||
int_to_hexbin(I, I_size) ->
|
||||
list_to_binary(int_to_hexstr(I, I_size)).
|
||||
|
||||
checksum(Bin) when is_binary(Bin) ->
|
||||
crypto:hash(md5, Bin).
|
||||
%% @doc Calculate a checksum for a chunk of file data.
|
||||
|
||||
checksum_chunk(Chunk) when is_binary(Chunk); is_list(Chunk) ->
|
||||
crypto:hash(sha, Chunk).
|
||||
|
||||
%% @doc Log a verbose message.
|
||||
|
||||
verb(Fmt) ->
|
||||
verb(Fmt, []).
|
||||
|
||||
%% @doc Log a verbose message.
|
||||
|
||||
verb(Fmt, Args) ->
|
||||
case application:get_env(kernel, verbose) of
|
||||
{ok, true} -> io:format(Fmt, Args);
|
||||
_ -> ok
|
||||
end.
|
||||
|
||||
%% @doc Log an 'info' level message.
|
||||
|
||||
info_msg(Fmt, Args) ->
|
||||
case application:get_env(kernel, verbose) of {ok, false} -> ok;
|
||||
_ -> error_logger:info_msg(Fmt, Args)
|
||||
|
@ -165,11 +202,15 @@ info_msg(Fmt, Args) ->
|
|||
|
||||
%%%%%%%%%%%%%%%%%
|
||||
|
||||
%% @doc Create a TCP connection to a remote Machi server.
|
||||
|
||||
-spec connect(inet:ip_address() | inet:hostname(), inet:port_number()) ->
|
||||
port().
|
||||
connect(Host, Port) ->
|
||||
escript_connect(Host, Port, 4500).
|
||||
|
||||
%% @doc Create a TCP connection to a remote Machi server.
|
||||
|
||||
-spec connect(inet:ip_address() | inet:hostname(), inet:port_number(),
|
||||
timeout()) ->
|
||||
port().
|
||||
|
|
Loading…
Reference in a new issue