Skip to content
Browse files

Make the ring manager responsible for loading the ring

Change riak_core_ring_manager and riak_core_app so that the ring manager
is responsible for loading the ring file from the disk rather than starting
with an initially empty ring and then relying upon the riak_core app to
later load the ring. This avoids a race condition with the ring manager
writing the empty ring to the disk before the riak_core app loads the
prior ring.

Note: Riak previously relied upon starting with a fresh ring in order to
ensure secondary vnodes were started in case any had fallback data that
needed to be handed off. The act of starting secondaries has long since
been moved to the riak_core_vnode_manager that periodically starts up
secondary vnodes over time, therefore there is no longer any need to
start with a fresh ring. This commit will therefore always load a saved
ring when the ring_manager starts, rather than starting with a fresh ring.
  • Loading branch information...
1 parent 5404bf8 commit 0765c3a5dcce98b9c9bf96d8553eacfc1e0dacf5 @jtuple jtuple committed Jul 21, 2012
Showing with 27 additions and 34 deletions.
  1. +0 −22 src/riak_core_app.erl
  2. +25 −12 src/riak_core_ring_manager.erl
  3. +2 −0 test/bucket_fixup_test.erl
View
22 src/riak_core_app.erl
@@ -77,28 +77,6 @@ start(_StartType, _StartArgs) ->
{ok, Pid} ->
riak_core:register(riak_core, [{stat_mod, riak_core_stat}]),
ok = riak_core_ring_events:add_guarded_handler(riak_core_ring_handler, []),
- %% App is running; search for latest ring file and initialize with it
- riak_core_ring_manager:prune_ringfiles(),
- case riak_core_ring_manager:find_latest_ringfile() of
- {ok, RingFile} ->
- case riak_core_ring_manager:read_ringfile(RingFile) of
- {error, Reason} ->
- lager:critical("Failed to read ring file: ~p",
- [lager:posix_error(Reason)]),
- throw({error, Reason});
- Ring0 ->
- %% Upgrade the ring data structure if necessary.
- Ring = riak_core_ring:upgrade(Ring0),
- riak_core_ring_manager:set_my_ring(Ring)
- end;
- {error, not_found} ->
- riak_core_ring_manager:write_ringfile(),
- lager:warning("No ring file available.");
- {error, Reason} ->
- lager:critical("Failed to load ring file: ~p",
- [lager:posix_error(Reason)]),
- throw({error, Reason})
- end,
%% Register capabilities
riak_core_capability:register({riak_core, vnode_routing},
View
37 src/riak_core_ring_manager.erl
@@ -206,22 +206,35 @@ stop() ->
%% ===================================================================
init([Mode]) ->
- case Mode of
- live ->
- Ring = riak_core_ring:fresh();
- test ->
- Ring = riak_core_ring:fresh(16,node())
- end,
-
- %% Set the ring and send initial notification to local observers that
- %% ring has changed.
- %% Do *not* save the ring to disk here. On startup we deliberately come
- %% up with a ring where the local node owns all partitions so that any
- %% fallback vnodes will be started so they can hand off.
+ Ring = reload_ring(Mode),
set_ring_global(Ring),
riak_core_ring_events:ring_update(Ring),
{ok, #state{mode = Mode, raw_ring=Ring}}.
+reload_ring(test) ->
+ riak_core_ring:fresh(16,node());
+reload_ring(live) ->
+ case riak_core_ring_manager:find_latest_ringfile() of
+ {ok, RingFile} ->
+ case riak_core_ring_manager:read_ringfile(RingFile) of
+ {error, Reason} ->
+ lager:critical("Failed to read ring file: ~p",
+ [lager:posix_error(Reason)]),
+ throw({error, Reason});
+ Ring0 ->
+ %% Upgrade the ring data structure if necessary.
+ lager:info("Upgrading legacy ring"),
+ Ring = riak_core_ring:upgrade(Ring0),
+ Ring
+ end;
+ {error, not_found} ->
+ lager:warning("No ring file available."),
+ riak_core_ring:fresh();
+ {error, Reason} ->
+ lager:critical("Failed to load ring file: ~p",
+ [lager:posix_error(Reason)]),
+ throw({error, Reason})
+ end.
handle_call(get_raw_ring, _From, #state{raw_ring=Ring} = State) ->
{reply, {ok, Ring}, State};
View
2 test/bucket_fixup_test.erl
@@ -82,6 +82,8 @@ io:format(user, "BBOT DBG: ~p ~p ~p\n", [?MODULE, ?LINE, Ls2]),
catch(riak_core_ring_manager:stop()),
catch(exit(whereis(riak_core_ring_events), shutdown)),
timer:sleep(1000),
+ riak_core_ring_events:start_link(),
+ riak_core_ring_manager:start_link(test),
application:load(riak_core),
application:set_env(riak_core, bucket_fixups, []),
application:set_env(riak_core, default_bucket_props, []),

0 comments on commit 0765c3a

Please sign in to comment.
Something went wrong with that request. Please try again.