diff --git a/README.md b/README.md index d83c0e6..adccbdb 100644 --- a/README.md +++ b/README.md @@ -65,5 +65,5 @@ resolved. Examples -------- -A very simple example application/release can be found in the -[samples](https://github.com/lindenbaum/lbm_kv/tree/master/samples) directory. +A very simple example application/release can be found +[here](https://github.com/lindenbaum/sequencer_sample). diff --git a/samples/sequencer/README.md b/samples/sequencer/README.md deleted file mode 100644 index 617f4d0..0000000 --- a/samples/sequencer/README.md +++ /dev/null @@ -1,26 +0,0 @@ - -sequencer -========= - -A very simple service providing distributed sequence numbers. To build it use - -```erlang -rebar3 do clean, compile, release -``` - -Now you have a release which can be started using the `start.sh` script. The -script will start a node and drop you on the console of the running node. - -The application comes with a simple process that periodically queries the next -available sequence number and logs in using `error_logger`. Ideally, you'll now -start a few nodes on different shells and look at the logged output. - -The [bootstrap](https://github.com/schlagert/bootstrap) project is used to -automatically discover and connect the different nodes (may take up to 10s). -The current (bootstrap) configuration allows up to three nodes to be started on -one host simultaneously. If you use multiple machines there's no limitation. - -What you should see is that `lbm_kv` distributes the sequence number among the -different nodes as soon as they connect. When a new node starts it's initial -sequence number is `0`, so you will see duplicates on these nodes. These will -disappear, when the nodes get connected. Feel free to kill/restart random nodes. diff --git a/samples/sequencer/apps/sequencer/src/sequencer.app.src b/samples/sequencer/apps/sequencer/src/sequencer.app.src deleted file mode 100644 index 0808e1f..0000000 --- a/samples/sequencer/apps/sequencer/src/sequencer.app.src +++ /dev/null @@ -1,36 +0,0 @@ -%%%============================================================================= -%%% -%%% | o __ _| _ __ |_ _ _ _ (TM) -%%% |_ | | | (_| (/_ | | |_) (_| |_| | | | -%%% -%%% @copyright (C) 2016, Lindenbaum GmbH -%%% -%%% Permission to use, copy, modify, and/or distribute this software for any -%%% purpose with or without fee is hereby granted, provided that the above -%%% copyright notice and this permission notice appear in all copies. -%%% -%%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -%%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -%%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -%%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -%%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -%%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -%%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -%%%============================================================================= -{application, - sequencer, - [ - {description, "A minimalistic, distributed sequence number provider."}, - {vsn, "0.0.0"}, - {registered, []}, - {applications, - [ - kernel, - stdlib, - sasl, - bootstrap, - lbm_kv - ]}, - {mod, {sequencer, []}}, - {env, []} - ]}. diff --git a/samples/sequencer/apps/sequencer/src/sequencer.erl b/samples/sequencer/apps/sequencer/src/sequencer.erl deleted file mode 100644 index 71b11d9..0000000 --- a/samples/sequencer/apps/sequencer/src/sequencer.erl +++ /dev/null @@ -1,123 +0,0 @@ -%%%============================================================================= -%%% -%%% | o __ _| _ __ |_ _ _ _ (TM) -%%% |_ | | | (_| (/_ | | |_) (_| |_| | | | -%%% -%%% @copyright (C) 2016, Lindenbaum GmbH -%%% -%%% Permission to use, copy, modify, and/or distribute this software for any -%%% purpose with or without fee is hereby granted, provided that the above -%%% copyright notice and this permission notice appear in all copies. -%%% -%%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -%%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -%%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -%%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -%%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -%%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -%%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -%%% -%%% @doc -%%% A very simple application providing distributed sequence numbers. -%%% -%%% Keep calm, after all this is only a sample application and does not handle -%%% duplicates which will of course occur in case of network splits (or on -%%% startup before nodes get connected). -%%% @end -%%%============================================================================= - --module(sequencer). - --behaviour(lbm_kv). --behaviour(application). --behaviour(supervisor). - -%% API --export([next/0]). - -%% lbm_kv callbacks --export([handle_conflict/3]). - -%% Application callbacks --export([start/2, stop/1]). - -%% supervisor callbacks --export([init/1]). - --define(KEY, sequence_number). - -%%%============================================================================= -%%% API -%%%============================================================================= - -%%------------------------------------------------------------------------------ -%% @doc -%% Returns the next sequence number. Returns an error if the database is not yet -%% initialized. -%% @end -%%------------------------------------------------------------------------------ --spec next() -> non_neg_integer(). -next() -> - {ok, [{?KEY, Value}]} = lbm_kv:update(?MODULE, ?KEY, fun update_db/2), - Value + 1. - -%%%============================================================================= -%%% lbm_kv callbacks -%%%============================================================================= - -%%------------------------------------------------------------------------------ -%% @private -%% Just use the highest sequence number. -%%------------------------------------------------------------------------------ --spec handle_conflict(?KEY, non_neg_integer(), non_neg_integer()) -> - {value, non_neg_integer()}. -handle_conflict(?KEY, Local, Remote) -> {value, max(Local, Remote)}. - -%%%============================================================================= -%%% Application callbacks -%%%============================================================================= - -%%------------------------------------------------------------------------------ -%% @private -%%------------------------------------------------------------------------------ -start(_StartType, _StartArgs) -> supervisor:start_link(?MODULE, []). - -%%------------------------------------------------------------------------------ -%% @private -%%------------------------------------------------------------------------------ -stop(_State) -> ok. - -%%%============================================================================= -%%% supervisor callbacks -%%%============================================================================= - -%%------------------------------------------------------------------------------ -%% @private -%%------------------------------------------------------------------------------ -init([]) -> - ok = lbm_kv:create(?MODULE), - {ok, _} = lbm_kv:update(?MODULE, ?KEY, fun init_db/2), - {ok, {{one_for_one, 5, 1}, [spec(sequencer_logger)]}}. - -%%%============================================================================= -%%% internal functions -%%%============================================================================= - -%%------------------------------------------------------------------------------ -%% @private -%%------------------------------------------------------------------------------ -spec(M) -> {M, {M, start_link, []}, permanent, 1000, worker, [M]}. - -%%------------------------------------------------------------------------------ -%% @private -%% Initialize the DB with sequence number `0', if not already initialized by -%% merge. -%%------------------------------------------------------------------------------ -init_db(?KEY, undefined) -> {value, 0}; -init_db(?KEY, Other) -> Other. - -%%------------------------------------------------------------------------------ -%% @private -%% Update the sequence number by one. -%%------------------------------------------------------------------------------ -update_db(?KEY, {value, Value}) -> {value, Value + 1}. diff --git a/samples/sequencer/apps/sequencer/src/sequencer_logger.erl b/samples/sequencer/apps/sequencer/src/sequencer_logger.erl deleted file mode 100644 index 3da37c7..0000000 --- a/samples/sequencer/apps/sequencer/src/sequencer_logger.erl +++ /dev/null @@ -1,112 +0,0 @@ -%%%============================================================================= -%%% -%%% | o __ _| _ __ |_ _ _ _ (TM) -%%% |_ | | | (_| (/_ | | |_) (_| |_| | | | -%%% -%%% @copyright (C) 2016, Lindenbaum GmbH -%%% -%%% Permission to use, copy, modify, and/or distribute this software for any -%%% purpose with or without fee is hereby granted, provided that the above -%%% copyright notice and this permission notice appear in all copies. -%%% -%%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -%%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -%%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -%%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -%%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -%%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -%%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -%%% -%%% @doc -%%% A simple server periodically aquiring and logging a new sequence number. -%%% @end -%%%============================================================================= - --module(sequencer_logger). - --behaviour(gen_server). - -%% Internal API --export([start_link/0]). - -%% gen_server callbacks --export([init/1, - handle_cast/2, - handle_call/3, - handle_info/2, - code_change/3, - terminate/2]). - --include_lib("bootstrap/include/bootstrap.hrl"). - -%%%============================================================================= -%%% Internal API -%%%============================================================================= - -%%------------------------------------------------------------------------------ -%% @private -%%------------------------------------------------------------------------------ --spec start_link() -> {ok, pid()} | {error, term()}. -start_link() -> gen_server:start_link(?MODULE, [], []). - -%%%============================================================================= -%%% gen_server callbacks -%%%============================================================================= - --record(state, {timer :: reference()}). - -%%------------------------------------------------------------------------------ -%% @private -%%------------------------------------------------------------------------------ -init([]) -> - ok = bootstrap:monitor_nodes(true), - {ok, #state{timer = schedule_next()}}. - -%%------------------------------------------------------------------------------ -%% @private -%%------------------------------------------------------------------------------ -handle_call(_Request, _From, State) -> {reply, undef, State}. - -%%------------------------------------------------------------------------------ -%% @private -%%------------------------------------------------------------------------------ -handle_cast(_Request, State) -> {noreply, State}. - -%%------------------------------------------------------------------------------ -%% @private -%%------------------------------------------------------------------------------ -handle_info(?BOOTSTRAP_UP(Node), State) -> - error_logger:info_msg("Node ~s joined the cluster~n", [Node]), - {noreply, State}; -handle_info(?BOOTSTRAP_DOWN(Node, Reason), State) -> - error_logger:info_msg("Node ~s left the cluster (~w)~n", [Node, Reason]), - {noreply, State}; -handle_info({timeout, Ref, next}, State = #state{timer = Ref}) -> - ok = log(sequencer:next()), - {noreply, State#state{timer = schedule_next()}}; -handle_info(_Info, State) -> - {noreply, State}. - -%%------------------------------------------------------------------------------ -%% @private -%%------------------------------------------------------------------------------ -code_change(_OldVsn, State, _Extra) -> {ok, State}. - -%%------------------------------------------------------------------------------ -%% @private -%%------------------------------------------------------------------------------ -terminate(_Reason, _State) -> ok. - -%%%============================================================================= -%%% Internal functions -%%%============================================================================= - -%%------------------------------------------------------------------------------ -%% @private -%%------------------------------------------------------------------------------ -schedule_next() -> erlang:start_timer(5000, self(), next). - -%%------------------------------------------------------------------------------ -%% @private -%%------------------------------------------------------------------------------ -log(N) -> error_logger:info_msg("Current sequence number is ~w~n", [N]). diff --git a/samples/sequencer/config/sys.config b/samples/sequencer/config/sys.config deleted file mode 100644 index d0baa3b..0000000 --- a/samples/sequencer/config/sys.config +++ /dev/null @@ -1,37 +0,0 @@ -%%%============================================================================= -%%% -%%% | o __ _| _ __ |_ _ _ _ (TM) -%%% |_ | | | (_| (/_ | | |_) (_| |_| | | | -%%% -%%% Copyright (c) 2016 Lindenbaum GmbH -%%% -%%% Permission to use, copy, modify, and/or distribute this software for any -%%% purpose with or without fee is hereby granted, provided that the above -%%% copyright notice and this permission notice appear in all copies. -%%% -%%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -%%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -%%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -%%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -%%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -%%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -%%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -%%%============================================================================= - -[ - {kernel, - [ - {start_timer, true} - ]}, - {bootstrap, - [ - {connect_regex, "sequencer(-\\d)?@"}, - {min_connections, 2}, - {protocol, broadcast} - ]}, - {lbm_kv, - [ - {retries, 3}, - {retry_timeout, 1000} - ]} -]. diff --git a/samples/sequencer/config/vm.args b/samples/sequencer/config/vm.args deleted file mode 100644 index 2ea962b..0000000 --- a/samples/sequencer/config/vm.args +++ /dev/null @@ -1,24 +0,0 @@ -################################################################################ -# -# | o __ _| _ __ |_ _ _ _ (TM) -# |_ | | | (_| (/_ | | |_) (_| |_| | | | -# -# Copyright (c) 2016 Lindenbaum GmbH -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -################################################################################ - --name sequencer${NODE_INDEX} --setcookie cookie - -+K true diff --git a/samples/sequencer/rebar.config b/samples/sequencer/rebar.config deleted file mode 100644 index 8c195b9..0000000 --- a/samples/sequencer/rebar.config +++ /dev/null @@ -1,51 +0,0 @@ -%%%============================================================================= -%%% -%%% | o __ _| _ __ |_ _ _ _ (TM) -%%% |_ | | | (_| (/_ | | |_) (_| |_| | | | -%%% -%%% Copyright (c) 2016 Lindenbaum GmbH -%%% -%%% Permission to use, copy, modify, and/or distribute this software for any -%%% purpose with or without fee is hereby granted, provided that the above -%%% copyright notice and this permission notice appear in all copies. -%%% -%%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -%%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -%%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -%%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -%%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -%%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -%%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -%%%============================================================================= - -{deps, - [ - {bootstrap, "0.0.2"}, - {lbm_kv, "0.0.2"} - ]}. - -{relx, - [ - {release, - {sequencer_sample, "0.0.0"}, - [ - %% Erlang/OTP - kernel, - stdlib, - sasl, - crypto, - mnesia, - - %% third-party - bootstrap, - - %% project - lbm_kv, - sequencer - ]}, - {sys_config, "./config/sys.config"}, - {vm_args, "./config/vm.args"}, - {dev_mode, true}, - {include_erts, true}, - {extended_start_script, true} - ]}. diff --git a/samples/sequencer/rebar.lock b/samples/sequencer/rebar.lock deleted file mode 100644 index cd8cac5..0000000 --- a/samples/sequencer/rebar.lock +++ /dev/null @@ -1,2 +0,0 @@ -[{<<"bootstrap">>,{pkg,<<"bootstrap">>,<<"0.0.2">>},0}, - {<<"lbm_kv">>,{pkg,<<"lbm_kv">>,<<"0.0.2">>},0}]. diff --git a/samples/sequencer/start.sh b/samples/sequencer/start.sh deleted file mode 100755 index 679a441..0000000 --- a/samples/sequencer/start.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash -################################################################################ -# -# | o __ _| _ __ |_ _ _ _ (TM) -# |_ | | | (_| (/_ | | |_) (_| |_| | | | -# -# @copyright (C) 2016, Lindenbaum GmbH -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -################################################################################ - -USAGE=" -A scipt to start a node running the sequencer_sample release. - - $0 - -where: - NODE_INDEX The index of the node to start. -" - -if [ -z "$1" ]; then - echo "$USAGE" - exit 1 -fi - -export RELX_REPLACE_OS_VARS=true -NODE_INDEX="-$1" _build/default/rel/sequencer_sample/bin/sequencer_sample console