/
riak_core.erl
145 lines (134 loc) · 5.57 KB
/
riak_core.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
%% -------------------------------------------------------------------
%%
%% Riak: A lightweight, decentralized key-value store.
%%
%% Copyright (c) 2007-2011 Basho Technologies, Inc. All Rights Reserved.
%%
%% This file is provided to you under the Apache License,
%% Version 2.0 (the "License"); you may not use this file
%% except in compliance with the License. You may obtain
%% a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing,
%% software distributed under the License is distributed on an
%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
%% KIND, either express or implied. See the License for the
%% specific language governing permissions and limitations
%% under the License.
%%
%% -------------------------------------------------------------------
-module(riak_core).
-export([stop/0, stop/1, join/1, remove_from_cluster/1]).
-export([register_vnode_module/1, vnode_modules/0]).
-export([add_guarded_event_handler/3, add_guarded_event_handler/4]).
-export([delete_guarded_event_handler/3]).
%% @spec stop() -> ok
%% @doc Stop the riak application and the calling process.
stop() -> stop("riak stop requested").
-ifdef(TEST).
stop(Reason) ->
error_logger:info_msg(io_lib:format("~p~n",[Reason])),
% if we're in test mode, we don't want to halt the node, so instead
% we just stop the application.
application:stop(riak_core).
-else.
stop(Reason) ->
% we never do an application:stop because that makes it very hard
% to really halt the runtime, which is what we need here.
error_logger:info_msg(io_lib:format("~p~n",[Reason])),
init:stop().
-endif.
%%
%% @doc Join the ring found on the specified remote node
%%
join(NodeStr) when is_list(NodeStr) ->
join(riak_core_util:str_to_node(NodeStr));
join(Node) when is_atom(Node) ->
{ok, OurRingSize} = application:get_env(riak_core, ring_creation_size),
case net_adm:ping(Node) of
pong ->
case rpc:call(Node,
application,
get_env,
[riak_core, ring_creation_size]) of
{ok, OurRingSize} ->
riak_core_gossip:send_ring(Node, node());
_ ->
{error, different_ring_sizes}
end;
pang ->
{error, not_reachable}
end.
%% @spec remove_from_cluster(ExitingNode :: atom()) -> term()
%% @doc Cause all partitions owned by ExitingNode to be taken over
%% by other nodes.
remove_from_cluster(ExitingNode) when is_atom(ExitingNode) ->
riak_core_gossip:remove_from_cluster(ExitingNode).
vnode_modules() ->
case application:get_env(riak_core, vnode_modules) of
undefined -> [];
{ok, Mods} -> Mods
end.
register_vnode_module(VNodeMod) when is_atom(VNodeMod) ->
{ok, App} = case application:get_application(self()) of
{ok, AppName} -> {ok, AppName};
undefined -> app_for_module(VNodeMod)
end,
case application:get_env(riak_core, vnode_modules) of
undefined ->
application:set_env(riak_core, vnode_modules, [{App,VNodeMod}]);
{ok, Mods} ->
application:set_env(riak_core, vnode_modules, [{App,VNodeMod}|Mods])
end,
riak_core_ring_events:force_sync_update().
%% @spec add_guarded_event_handler(HandlerMod, Handler, Args) -> AddResult
%% HandlerMod = module()
%% Handler = module() | {module(), term()}
%% Args = list()
%% AddResult = ok | {error, Reason::term()}
add_guarded_event_handler(HandlerMod, Handler, Args) ->
add_guarded_event_handler(HandlerMod, Handler, Args, undefined).
%% @spec add_guarded_event_handler(HandlerMod, Handler, Args, ExitFun) -> AddResult
%% HandlerMod = module()
%% Handler = module() | {module(), term()}
%% Args = list()
%% ExitFun = fun(Handler, Reason::term())
%% AddResult = ok | {error, Reason::term()}
%%
%% @doc Add a "guarded" event handler to a gen_event instance.
%% A guarded handler is implemented as a supervised gen_server
%% (riak_core_eventhandler_guard) that adds a supervised handler in its
%% init() callback and exits when the handler crashes so it can be
%% restarted by the supervisor.
add_guarded_event_handler(HandlerMod, Handler, Args, ExitFun) ->
riak_core_eventhandler_sup:start_guarded_handler(HandlerMod, Handler, Args, ExitFun).
%% @spec delete_guarded_event_handler(HandlerMod, Handler, Args) -> Result
%% HandlerMod = module()
%% Handler = module() | {module(), term()}
%% Args = term()
%% Result = term() | {error, module_not_found} | {'EXIT', Reason}
%% Reason = term()
%%
%% @doc Delete a guarded event handler from a gen_event instance.
%%
%% Args is an arbitrary term which is passed as one of the arguments to
%% Module:terminate/2.
%%
%% The return value is the return value of Module:terminate/2. If the
%% specified event handler is not installed, the function returns
%% {error,module_not_found}. If the callback function fails with Reason,
%% the function returns {'EXIT',Reason}.
delete_guarded_event_handler(HandlerMod, Handler, Args) ->
riak_core_eventhandler_sup:stop_guarded_handler(HandlerMod, Handler, Args).
app_for_module(Mod) ->
app_for_module(application:which_applications(), Mod).
app_for_module([], _Mod) ->
undefined;
app_for_module([{App,_,_}|T], Mod) ->
{ok, Mods} = application:get_key(App, modules),
case lists:member(Mod, Mods) of
true -> {ok, App};
false -> app_for_module(T, Mod)
end.