Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 222 lines (192 sloc) 8.62 kb
90f6ce8 @argv0 initial import
argv0 authored
1 %% -------------------------------------------------------------------
2 %%
3 %% riak_vnode_master: dispatch to vnodes
4 %%
5 %% Copyright (c) 2007-2010 Basho Technologies, Inc. All Rights Reserved.
6 %%
7 %% This file is provided to you under the Apache License,
8 %% Version 2.0 (the "License"); you may not use this file
9 %% except in compliance with the License. You may obtain
10 %% a copy of the License at
11 %%
12 %% http://www.apache.org/licenses/LICENSE-2.0
13 %%
14 %% Unless required by applicable law or agreed to in writing,
15 %% software distributed under the License is distributed on an
16 %% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 %% KIND, either express or implied. See the License for the
18 %% specific language governing permissions and limitations
19 %% under the License.
20 %%
21 %% -------------------------------------------------------------------
22
23 %% @doc dispatch to vnodes
24
25 -module(riak_core_vnode_master).
ab29a5d @seancribbs Use include instead of include_lib for local include files.
seancribbs authored
26 -include("riak_core_vnode.hrl").
90f6ce8 @argv0 initial import
argv0 authored
27 -behaviour(gen_server).
28 -export([start_link/1, start_link/2, get_vnode_pid/2,
29 start_vnode/2, command/3, command/4, sync_command/3,
274db4a @kellymclaughlin Generalize the coverage behavior used to list keys and move much
kellymclaughlin authored
30 coverage/5,
a5b1766 @beerriot expose the pid for the vnode that just received the command
beerriot authored
31 command_return_vnode/4,
90f6ce8 @argv0 initial import
argv0 authored
32 sync_command/4,
33 sync_spawn_command/3, make_request/3,
0223283 @jtuple Refactor riak_core vnode management (part 2)
jtuple authored
34 make_coverage_request/4, all_nodes/1, reg_name/1]).
90f6ce8 @argv0 initial import
argv0 authored
35 -export([init/1, handle_call/3, handle_cast/2, handle_info/2,
36 terminate/2, code_change/3]).
312fcb7 @argv0 Remove unused exclusion list from riak_core_vnode_master state (bz://105...
argv0 authored
37 -record(state, {idxtab, sup_name, vnode_mod, legacy}).
90f6ce8 @argv0 initial import
argv0 authored
38
39 -define(DEFAULT_TIMEOUT, 5000).
40
41 make_name(VNodeMod,Suffix) -> list_to_atom(atom_to_list(VNodeMod)++Suffix).
42 reg_name(VNodeMod) -> make_name(VNodeMod, "_master").
43
f9e72f4 @jtuple Refactor riak_core vnode management (part 1)
jtuple authored
44 %% Given atom 'riak_kv_vnode_master', return 'riak_kv_vnode'.
45 vmaster_to_vmod(VMaster) ->
46 L = atom_to_list(VMaster),
47 list_to_atom(lists:sublist(L,length(L)-7)).
48
274db4a @kellymclaughlin Generalize the coverage behavior used to list keys and move much
kellymclaughlin authored
49 start_link(VNodeMod) ->
90f6ce8 @argv0 initial import
argv0 authored
50 start_link(VNodeMod, undefined).
51
274db4a @kellymclaughlin Generalize the coverage behavior used to list keys and move much
kellymclaughlin authored
52 start_link(VNodeMod, LegacyMod) ->
90f6ce8 @argv0 initial import
argv0 authored
53 RegName = reg_name(VNodeMod),
274db4a @kellymclaughlin Generalize the coverage behavior used to list keys and move much
kellymclaughlin authored
54 gen_server:start_link({local, RegName}, ?MODULE,
90f6ce8 @argv0 initial import
argv0 authored
55 [VNodeMod,LegacyMod,RegName], []).
56
57 start_vnode(Index, VNodeMod) ->
f9e72f4 @jtuple Refactor riak_core vnode management (part 1)
jtuple authored
58 riak_core_vnode_manager:start_vnode(Index, VNodeMod).
90f6ce8 @argv0 initial import
argv0 authored
59
60 get_vnode_pid(Index, VNodeMod) ->
f9e72f4 @jtuple Refactor riak_core vnode management (part 1)
jtuple authored
61 riak_core_vnode_manager:get_vnode_pid(Index, VNodeMod).
274db4a @kellymclaughlin Generalize the coverage behavior used to list keys and move much
kellymclaughlin authored
62
90f6ce8 @argv0 initial import
argv0 authored
63 command(Preflist, Msg, VMaster) ->
da17dbd @jonmeredith Change default vnode request sender to 'ignore'.
jonmeredith authored
64 command(Preflist, Msg, ignore, VMaster).
274db4a @kellymclaughlin Generalize the coverage behavior used to list keys and move much
kellymclaughlin authored
65
90f6ce8 @argv0 initial import
argv0 authored
66 %% Send the command to the preflist given with responses going to Sender
67 command([], _Msg, _Sender, _VMaster) ->
68 ok;
9dded97 @jonmeredith Added a variant of preference lists with Pids rather than indices.
jonmeredith authored
69 command([{Index, Pid}|Rest], Msg, Sender, VMaster) when is_pid(Pid) ->
70 gen_fsm:send_event(Pid, make_request(Msg, Sender, Index)),
71 command(Rest, Msg, Sender, VMaster);
90f6ce8 @argv0 initial import
argv0 authored
72 command([{Index,Node}|Rest], Msg, Sender, VMaster) ->
f9e72f4 @jtuple Refactor riak_core vnode management (part 1)
jtuple authored
73 proxy_cast({VMaster, Node}, make_request(Msg, Sender, Index)),
90f6ce8 @argv0 initial import
argv0 authored
74 command(Rest, Msg, Sender, VMaster);
75
76 %% Send the command to an individual Index/Node combination
6af5ab5 @jonmeredith Add Pid-based variant for single-node commands.
jonmeredith authored
77 command({Index, Pid}, Msg, Sender, _VMaster) when is_pid(Pid) ->
78 gen_fsm:send_event(Pid, make_request(Msg, Sender, Index));
90f6ce8 @argv0 initial import
argv0 authored
79 command({Index,Node}, Msg, Sender, VMaster) ->
f9e72f4 @jtuple Refactor riak_core vnode management (part 1)
jtuple authored
80 proxy_cast({VMaster, Node}, make_request(Msg, Sender, Index)).
90f6ce8 @argv0 initial import
argv0 authored
81
274db4a @kellymclaughlin Generalize the coverage behavior used to list keys and move much
kellymclaughlin authored
82 %% Send a command to a covering set of vnodes
c4b8013 @jtuple Overhaul cluster membership, ring format, and gossip protocol
jtuple authored
83 coverage(Msg, CoverageVNodes, Keyspaces, {Type, Ref, From}, VMaster)
84 when is_list(CoverageVNodes) ->
f9e72f4 @jtuple Refactor riak_core vnode management (part 1)
jtuple authored
85 [proxy_cast({VMaster, Node},
86 make_coverage_request(Msg,
87 Keyspaces,
88 {Type, {Ref, {Index, Node}}, From},
89 Index)) ||
c4b8013 @jtuple Overhaul cluster membership, ring format, and gossip protocol
jtuple authored
90 {Index, Node} <- CoverageVNodes];
91 coverage(Msg, {Index, Node}, Keyspaces, Sender, VMaster) ->
f9e72f4 @jtuple Refactor riak_core vnode management (part 1)
jtuple authored
92 proxy_cast({VMaster, Node},
93 make_coverage_request(Msg, Keyspaces, Sender, Index)).
c4b8013 @jtuple Overhaul cluster membership, ring format, and gossip protocol
jtuple authored
94
a5b1766 @beerriot expose the pid for the vnode that just received the command
beerriot authored
95 %% Send the command to an individual Index/Node combination, but also
96 %% return the pid for the vnode handling the request, as `{ok,
97 %% VnodePid}'.
98 command_return_vnode({Index,Node}, Msg, Sender, VMaster) ->
f9e72f4 @jtuple Refactor riak_core vnode management (part 1)
jtuple authored
99 Mod = vmaster_to_vmod(VMaster),
100 Req = make_request(Msg, Sender, Index),
101 riak_core_vnode_proxy:command_return_vnode({Mod,Index,Node}, Req).
a5b1766 @beerriot expose the pid for the vnode that just received the command
beerriot authored
102
90f6ce8 @argv0 initial import
argv0 authored
103 %% Send a synchronous command to an individual Index/Node combination.
104 %% Will not return until the vnode has returned
105 sync_command(IndexNode, Msg, VMaster) ->
106 sync_command(IndexNode, Msg, VMaster, ?DEFAULT_TIMEOUT).
107
108 sync_command({Index,Node}, Msg, VMaster, Timeout) ->
109 %% Issue the call to the master, it will update the Sender with
274db4a @kellymclaughlin Generalize the coverage behavior used to list keys and move much
kellymclaughlin authored
110 %% the From for handle_call so that the {reply} return gets
90f6ce8 @argv0 initial import
argv0 authored
111 %% sent here.
274db4a @kellymclaughlin Generalize the coverage behavior used to list keys and move much
kellymclaughlin authored
112 gen_server:call({VMaster, Node},
90f6ce8 @argv0 initial import
argv0 authored
113 make_request(Msg, {server, undefined, undefined}, Index), Timeout).
114
115 %% Send a synchronous spawned command to an individual Index/Node combination.
116 %% Will not return until the vnode has returned, but the vnode_master will
117 %% continue to handle requests.
118 sync_spawn_command({Index,Node}, Msg, VMaster) ->
274db4a @kellymclaughlin Generalize the coverage behavior used to list keys and move much
kellymclaughlin authored
119 gen_server:call({VMaster, Node},
90f6ce8 @argv0 initial import
argv0 authored
120 {spawn, make_request(Msg, {server, undefined, undefined}, Index)},
121 infinity).
122
274db4a @kellymclaughlin Generalize the coverage behavior used to list keys and move much
kellymclaughlin authored
123
90f6ce8 @argv0 initial import
argv0 authored
124 %% Make a request record - exported for use by legacy modules
125 -spec make_request(vnode_req(), sender(), partition()) -> #riak_vnode_req_v1{}.
126 make_request(Request, Sender, Index) ->
127 #riak_vnode_req_v1{
128 index=Index,
129 sender=Sender,
130 request=Request}.
131
274db4a @kellymclaughlin Generalize the coverage behavior used to list keys and move much
kellymclaughlin authored
132 %% Make a request record - exported for use by legacy modules
133 -spec make_coverage_request(vnode_req(), [{partition(), [partition()]}], sender(), partition()) -> #riak_coverage_req_v1{}.
134 make_coverage_request(Request, KeySpaces, Sender, Index) ->
135 #riak_coverage_req_v1{index=Index,
136 keyspaces=KeySpaces,
137 sender=Sender,
138 request=Request}.
139
0223283 @jtuple Refactor riak_core vnode management (part 2)
jtuple authored
140 %% Request a list of Pids for all vnodes
141 %% @deprecated
142 %% Provided for compatibility with older vnode master API. New code should
143 %% use riak_core_vnode_manager:all_vnode/1 which returns a mod/index/pid
144 %% list rather than just a pid list.
145 all_nodes(VNodeMod) ->
146 VNodes = riak_core_vnode_manager:all_vnodes(VNodeMod),
147 [Pid || {_Mod, _Idx, Pid} <- VNodes].
148
90f6ce8 @argv0 initial import
argv0 authored
149 %% @private
f9e72f4 @jtuple Refactor riak_core vnode management (part 1)
jtuple authored
150 init([VNodeMod, LegacyMod, _RegName]) ->
151 {ok, #state{idxtab=undefined,
90f6ce8 @argv0 initial import
argv0 authored
152 vnode_mod=VNodeMod,
153 legacy=LegacyMod}}.
154
f9e72f4 @jtuple Refactor riak_core vnode management (part 1)
jtuple authored
155 proxy_cast({VMaster, Node}, Req) ->
156 case app_helper:get_env(riak_core, legacy_vnode_routing, true) of
157 true ->
158 gen_server:cast({VMaster, Node}, Req);
159 false ->
160 do_proxy_cast({VMaster, Node}, Req)
161 end.
162
163 do_proxy_cast({VMaster, Node}, Req=?VNODE_REQ{index=Idx}) ->
164 Mod = vmaster_to_vmod(VMaster),
165 Proxy = riak_core_vnode_proxy:reg_name(Mod, Idx, Node),
166 gen_fsm:send_event(Proxy, Req),
167 ok;
168 do_proxy_cast({VMaster, Node}, Req=?COVERAGE_REQ{index=Idx}) ->
169 Mod = vmaster_to_vmod(VMaster),
170 Proxy = riak_core_vnode_proxy:reg_name(Mod, Idx, Node),
171 gen_fsm:send_event(Proxy, Req),
172 ok;
173 do_proxy_cast({VMaster, Node}, Other) ->
174 gen_server:cast({VMaster, Node}, Other).
175
176 handle_cast(Req=?VNODE_REQ{index=Idx}, State=#state{vnode_mod=Mod}) ->
177 Proxy = riak_core_vnode_proxy:reg_name(Mod, Idx),
178 gen_fsm:send_event(Proxy, Req),
274db4a @kellymclaughlin Generalize the coverage behavior used to list keys and move much
kellymclaughlin authored
179 {noreply, State};
f9e72f4 @jtuple Refactor riak_core vnode management (part 1)
jtuple authored
180 handle_cast(Req=?COVERAGE_REQ{index=Idx}, State=#state{vnode_mod=Mod}) ->
181 Proxy = riak_core_vnode_proxy:reg_name(Mod, Idx),
182 gen_fsm:send_event(Proxy, Req),
dd5672e @Vagabond Fixes to both the async worker cleanup and the EQC test for it
Vagabond authored
183 {noreply, State};
90f6ce8 @argv0 initial import
argv0 authored
184 handle_cast(Other, State=#state{legacy=Legacy}) when Legacy =/= undefined ->
185 case catch Legacy:rewrite_cast(Other) of
186 {ok, ?VNODE_REQ{}=Req} ->
187 handle_cast(Req, State);
188 _ ->
189 {noreply, State}
190 end.
191
f9e72f4 @jtuple Refactor riak_core vnode management (part 1)
jtuple authored
192 handle_call(Req=?VNODE_REQ{index=Idx, sender={server, undefined, undefined}},
193 From, State=#state{vnode_mod=Mod}) ->
194 Proxy = riak_core_vnode_proxy:reg_name(Mod, Idx),
195 gen_fsm:send_event(Proxy, Req?VNODE_REQ{sender={server, undefined, From}}),
90f6ce8 @argv0 initial import
argv0 authored
196 {noreply, State};
274db4a @kellymclaughlin Generalize the coverage behavior used to list keys and move much
kellymclaughlin authored
197 handle_call({spawn,
f9e72f4 @jtuple Refactor riak_core vnode management (part 1)
jtuple authored
198 Req=?VNODE_REQ{index=Idx, sender={server, undefined, undefined}}},
199 From, State=#state{vnode_mod=Mod}) ->
200 Proxy = riak_core_vnode_proxy:reg_name(Mod, Idx),
90f6ce8 @argv0 initial import
argv0 authored
201 Sender = {server, undefined, From},
7e14a88 @kellymclaughlin Use spawn_link in server call generated by a call to riak_core_vnode_mas...
kellymclaughlin authored
202 spawn_link(
f9e72f4 @jtuple Refactor riak_core vnode management (part 1)
jtuple authored
203 fun() -> gen_fsm:send_all_state_event(Proxy, Req?VNODE_REQ{sender=Sender}) end),
90f6ce8 @argv0 initial import
argv0 authored
204 {noreply, State};
205 handle_call(Other, From, State=#state{legacy=Legacy}) when Legacy =/= undefined ->
206 case catch Legacy:rewrite_call(Other, From) of
207 {ok, ?VNODE_REQ{}=Req} ->
208 handle_call(Req, From, State);
209 _ ->
210 {noreply, State}
211 end.
212
f9e72f4 @jtuple Refactor riak_core vnode management (part 1)
jtuple authored
213 handle_info(_Info, State) ->
90f6ce8 @argv0 initial import
argv0 authored
214 {noreply, State}.
215
216 %% @private
274db4a @kellymclaughlin Generalize the coverage behavior used to list keys and move much
kellymclaughlin authored
217 terminate(_Reason, _State) ->
90f6ce8 @argv0 initial import
argv0 authored
218 ok.
219
220 %% @private
221 code_change(_OldVsn, State, _Extra) -> {ok, State}.
Something went wrong with that request. Please try again.