Permalink
Browse files

Updated README, added failover and clustering code.

  • Loading branch information...
1 parent 72f74e2 commit 75bf69acf89b14d6405f8932dc5e04e73a7068f5 @jbrisbin committed Mar 28, 2012
Showing with 298 additions and 48 deletions.
  1. +6 −0 .gitignore
  2. +10 −16 README.md
  3. +0 −2 console.sh
  4. +1 −0 env.sh
  5. +114 −0 hello_world1.config
  6. +114 −0 hello_world2.config
  7. +2 −0 node1.sh
  8. +2 −0 node2.sh
  9. +2 −1 rebar.config
  10. +7 −5 src/hello_world_vnode.erl
  11. +40 −24 src/hello_world_vnode_dispatcher.erl
View
@@ -3,3 +3,9 @@ deps
ebin
log
.DS_Store
+
+.hosts.erlang
+
+.project
+
+.settings/org.erlide.core.prefs
View
@@ -28,23 +28,17 @@ sort of functionality. It's code 202 - Accepted.
### How do I use it?
-That depends on your use case. I would start with your own riak_core application that
-already has your own vnodes configured and started in it. You would then copy out the
-`hello_world_vnode_dispatcher.erl` file and put that into your application (it's a gen_server).
-You'll want to edit the the `loop` function to maybe parameterize the vnode you dispatch to.
-Maybe you want to make that based on mapping a query parameter or path segment to a vnode
-name (I wouldn't use direct vnode names as parameters in your web app as that would expose
-important information about the internal structure of your site to a potential attacker).
+To test out this code, build it by typing `make` then issue the command `./node1.sh`. Send a web request
+using curl or somesuch:
-You'll also likely want to parameterize the port your app starts on. I'm assuming you're a savvy-
-enough OTP-nician to figure out how to do that. This isn't a HOWTO so much as example code
-showing you how I did it. Grab what you need, throw away the rest! :)
-
-### Running this code
+ curl -v http://localhost:3000/
-To test out this code, build it by typing `make` then running the `./console.sh` script, which
-will start the Erlang console with the right parameters. Once started, send a web request.
+You should get "Hello World!" back.
- curl -v http://localhost:3000/
+To test the clustering capabilities, open a second console window and start another node using this `./node2.sh`
+script. Once started, the two nodes should be clustered together and in a riak_core ring together. Send
+another request like above to make sure both instances can respond.
-You should get "Hello World!" back.
+You know have a clustered web application! If you kill one of the processes, your application will continue
+to function (provided you send HTTP traffic to the other misultin server, of course...this is where an
+haproxy or other load-balancer would come in).
View
@@ -1,2 +0,0 @@
-#!/bin/bash
-erl -pa ebin -pa deps/*/ebin -s hello_world -name helloworld@localhost
View
@@ -0,0 +1 @@
+#NODENAME=helloworld1
View
@@ -0,0 +1,114 @@
+%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ft=erlang ts=4 sw=4 et
+[
+ {hello_world, [
+ {web_port, 3000},
+ {master_node, 'helloworld1@localhost'}
+ ]},
+
+ %% Riak Core config
+ {riak_core, [
+ %% Default location of ringstate
+ {ring_state_dir, "./data/ring1"},
+
+ %% http is a list of IP addresses and TCP ports that the Riak
+ %% HTTP interface will bind.
+ %{http, [ {"127.0.0.1", 8098 } ]},
+
+ %% https is a list of IP addresses and TCP ports that the Riak
+ %% HTTPS interface will bind.
+ %{https, [{ "127.0.0.1", 8098 }]},
+
+ %% Default cert and key locations for https can be overridden
+ %% with the ssl config variable, for example:
+ %{ssl, [
+ % {certfile, "./etc/cert.pem"},
+ % {keyfile, "./etc/key.pem"}
+ % ]},
+
+ %% riak_handoff_port is the TCP port that Riak uses for
+ %% intra-cluster data handoff.
+ {handoff_port, 8099 },
+
+ %% To encrypt riak_core intra-cluster data handoff traffic,
+ %% uncomment the following line and edit its path to an
+ %% appropriate certfile and keyfile. (This example uses a
+ %% single file with both items concatenated together.)
+ %{handoff_ssl_options, [{certfile, "/tmp/erlserver.pem"}]},
+
+ %% Platform-specific installation paths (substituted by rebar)
+ {platform_bin_dir, "./bin"},
+ {platform_data_dir, "./data"},
+ {platform_etc_dir, "./etc"},
+ {platform_lib_dir, "./lib"},
+ {platform_log_dir, "./log"}
+ ]},
+
+ %% Lager Config
+ {lager, [
+ %% What handlers to install with what arguments
+ %% The defaults for the logfiles are to rotate the files when
+ %% they reach 10Mb or at midnight, whichever comes first, and keep
+ %% the last 5 rotations. See the lager README for a description of
+ %% the time rotation format:
+ %% https://github.com/basho/lager/blob/master/README.org
+ %%
+ %% If you wish to disable rotation, you can either set the size to 0
+ %% and the rotation time to "", or instead specify a 2-tuple that only
+ %% consists of {Logfile, Level}.
+ {handlers, [
+ {lager_console_backend, info},
+ {lager_file_backend, [
+ {"./log/error.log", error, 10485760, "$D0", 5},
+ {"./log/console.log", info, 10485760, "$D0", 5}
+ ]}
+ ]},
+
+ %% Whether to write a crash log, and where.
+ %% Commented/omitted/undefined means no crash logger.
+ {crash_log, "./log/crash.log"},
+
+ %% Maximum size in bytes of events in the crash log - defaults to 65536
+ {crash_log_msg_size, 65536},
+
+ %% Maximum size of the crash log in bytes, before its rotated, set
+ %% to 0 to disable rotation - default is 0
+ {crash_log_size, 10485760},
+
+ %% What time to rotate the crash log - default is no time
+ %% rotation. See the lager README for a description of this format:
+ %% https://github.com/basho/lager/blob/master/README.org
+ {crash_log_date, "$D0"},
+
+ %% Number of rotated crash logs to keep, 0 means keep only the
+ %% current one - default is 0
+ {crash_log_count, 5},
+
+ %% Whether to redirect error_logger messages into lager - defaults to true
+ {error_logger_redirect, true}
+ ]},
+
+ %% riak_sysmon config
+ {riak_sysmon, [
+ %% To disable forwarding events of a particular type, use a
+ %% limit of 0.
+ {process_limit, 30},
+ {port_limit, 2},
+
+ %% Finding reasonable limits for a given workload is a matter
+ %% of experimentation.
+ {gc_ms_limit, 100},
+ {heap_word_limit, 40111000},
+
+ %% Configure the following items to 'false' to disable logging
+ %% of that event type.
+ {busy_port, true},
+ {busy_dist_port, true}
+ ]},
+
+ %% SASL config
+ {sasl, [
+ {sasl_error_logger, false}
+ ]}
+
+].
View
@@ -0,0 +1,114 @@
+%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
+%% ex: ft=erlang ts=4 sw=4 et
+[
+ {hello_world, [
+ {web_port, 3001},
+ {master_node, 'helloworld1@localhost'}
+ ]},
+
+ %% Riak Core config
+ {riak_core, [
+ %% Default location of ringstate
+ {ring_state_dir, "./data/ring2"},
+
+ %% http is a list of IP addresses and TCP ports that the Riak
+ %% HTTP interface will bind.
+ %{http, [ {"127.0.0.1", 8098 } ]},
+
+ %% https is a list of IP addresses and TCP ports that the Riak
+ %% HTTPS interface will bind.
+ %{https, [{ "127.0.0.1", 8098 }]},
+
+ %% Default cert and key locations for https can be overridden
+ %% with the ssl config variable, for example:
+ %{ssl, [
+ % {certfile, "./etc/cert.pem"},
+ % {keyfile, "./etc/key.pem"}
+ % ]},
+
+ %% riak_handoff_port is the TCP port that Riak uses for
+ %% intra-cluster data handoff.
+ {handoff_port, 8199 },
+
+ %% To encrypt riak_core intra-cluster data handoff traffic,
+ %% uncomment the following line and edit its path to an
+ %% appropriate certfile and keyfile. (This example uses a
+ %% single file with both items concatenated together.)
+ %{handoff_ssl_options, [{certfile, "/tmp/erlserver.pem"}]},
+
+ %% Platform-specific installation paths (substituted by rebar)
+ {platform_bin_dir, "./bin"},
+ {platform_data_dir, "./data"},
+ {platform_etc_dir, "./etc"},
+ {platform_lib_dir, "./lib"},
+ {platform_log_dir, "./log"}
+ ]},
+
+ %% Lager Config
+ {lager, [
+ %% What handlers to install with what arguments
+ %% The defaults for the logfiles are to rotate the files when
+ %% they reach 10Mb or at midnight, whichever comes first, and keep
+ %% the last 5 rotations. See the lager README for a description of
+ %% the time rotation format:
+ %% https://github.com/basho/lager/blob/master/README.org
+ %%
+ %% If you wish to disable rotation, you can either set the size to 0
+ %% and the rotation time to "", or instead specify a 2-tuple that only
+ %% consists of {Logfile, Level}.
+ {handlers, [
+ {lager_console_backend, info},
+ {lager_file_backend, [
+ {"./log/error.log", error, 10485760, "$D0", 5},
+ {"./log/console.log", info, 10485760, "$D0", 5}
+ ]}
+ ]},
+
+ %% Whether to write a crash log, and where.
+ %% Commented/omitted/undefined means no crash logger.
+ {crash_log, "./log/crash.log"},
+
+ %% Maximum size in bytes of events in the crash log - defaults to 65536
+ {crash_log_msg_size, 65536},
+
+ %% Maximum size of the crash log in bytes, before its rotated, set
+ %% to 0 to disable rotation - default is 0
+ {crash_log_size, 10485760},
+
+ %% What time to rotate the crash log - default is no time
+ %% rotation. See the lager README for a description of this format:
+ %% https://github.com/basho/lager/blob/master/README.org
+ {crash_log_date, "$D0"},
+
+ %% Number of rotated crash logs to keep, 0 means keep only the
+ %% current one - default is 0
+ {crash_log_count, 5},
+
+ %% Whether to redirect error_logger messages into lager - defaults to true
+ {error_logger_redirect, true}
+ ]},
+
+ %% riak_sysmon config
+ {riak_sysmon, [
+ %% To disable forwarding events of a particular type, use a
+ %% limit of 0.
+ {process_limit, 30},
+ {port_limit, 2},
+
+ %% Finding reasonable limits for a given workload is a matter
+ %% of experimentation.
+ {gc_ms_limit, 100},
+ {heap_word_limit, 40111000},
+
+ %% Configure the following items to 'false' to disable logging
+ %% of that event type.
+ {busy_port, true},
+ {busy_dist_port, true}
+ ]},
+
+ %% SASL config
+ {sasl, [
+ {sasl_error_logger, false}
+ ]}
+
+].
View
@@ -0,0 +1,2 @@
+#!/bin/bash
+erl +K true +A 5 -pa ebin -pa deps/*/ebin -config hello_world1 -s hello_world -sname helloworld1@localhost
View
@@ -0,0 +1,2 @@
+#!/bin/bash
+erl +K true +A 5 -pa ebin -pa deps/*/ebin -config hello_world2 -s hello_world -sname helloworld2@localhost
View
@@ -1,6 +1,7 @@
{cover_enabled, true}.
{erl_opts, [
- debug_info
+ debug_info,
+ {parse_transform, lager_transform}
%fail_on_warning
]}.
@@ -30,7 +30,7 @@ start_vnode(I) ->
riak_core_vnode_master:get_vnode_pid(I, ?MODULE).
init([Partition]) ->
- %%io:format("started hello world vnode at ~p~n", [Partition]),
+ lager:debug("started ~p at partition ~p", [?MODULE, Partition]),
{ok, #state { partition = Partition }}.
handle_command({'GET', [], Req}, _Sender, State) ->
@@ -39,17 +39,19 @@ handle_command({'GET', [], Req}, _Sender, State) ->
{reply, {ok, Response}, State};
handle_command({_, _, Req}, _Sender, State) ->
- io:format("unhandled command: ~p~n", [Req]),
+ lager:warning("unhandled command: ~p~n", [Req]),
{reply, {ok, Req:respond(404)}, State}.
handle_coverage(Request, KeySpaces, Sender, State) ->
- io:format("handle_coverage: ~p ~p ~p ~p~n", [Request, KeySpaces, Sender, State]),
+ lager:debug("handle_coverage: ~p ~p ~p ~p~n", [Request, KeySpaces, Sender, State]),
{continue, State}.
-handle_exit(_Pid, Reason, State) ->
+handle_exit(Pid, Reason, State) ->
+ lager:debug("handle exit: ~p ~p~n", [Pid, Reason]),
{stop, Reason, State}.
-handle_handoff_command(_Message, _Sender, State) ->
+handle_handoff_command(Message, Sender, State) ->
+ lager:debug("handle handoff: ~p ~p~n", [Message, Sender]),
{forward, State}.
handoff_starting(_TargetNode, State) ->
Oops, something went wrong.

0 comments on commit 75bf69a

Please sign in to comment.