Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
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...
commit 0765c3a5dcce98b9c9bf96d8553eacfc1e0dacf5 1 parent 5404bf8
Joseph Blomstedt jtuple authored
22 src/riak_core_app.erl
View
@@ -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},
37 src/riak_core_ring_manager.erl
View
@@ -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};
2  test/bucket_fixup_test.erl
View
@@ -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, []),
Please sign in to comment.
Something went wrong with that request. Please try again.