basic vnode management stuff
This commit is contained in:
parent
d2a77bb174
commit
281938a05d
5 changed files with 142 additions and 1 deletions
|
@ -20,7 +20,10 @@ init([]) ->
|
|||
intensity => 0,
|
||||
period => 1
|
||||
},
|
||||
ChildSpecs = [],
|
||||
ChildSpecs = [
|
||||
#{id => vnode_manager, start => {kv_vnode_manager, start_link, []}, type => worker},
|
||||
#{id => vnode_sup, start => {kv_vnode_sup, start_link, []}, type => supervisor}
|
||||
],
|
||||
{ok, {SupFlags, ChildSpecs}}.
|
||||
|
||||
%%% internal functions
|
||||
|
|
58
apps/kv/src/kv_vnode.erl
Normal file
58
apps/kv/src/kv_vnode.erl
Normal file
|
@ -0,0 +1,58 @@
|
|||
-module(kv_vnode).
|
||||
-moduledoc """
|
||||
Holds data for a single partition in the ring.
|
||||
""".
|
||||
|
||||
-behaviour(gen_server).
|
||||
|
||||
-export([
|
||||
start_link/1,
|
||||
get/2,
|
||||
put/3
|
||||
]).
|
||||
|
||||
%%% gen_server callbacks
|
||||
-export([
|
||||
init/1,
|
||||
handle_call/3,
|
||||
handle_cast/2
|
||||
]).
|
||||
|
||||
-record(kv_vnode, {
|
||||
index :: non_neg_integer(),
|
||||
table :: ets:table()
|
||||
}).
|
||||
|
||||
-type state() :: #kv_vnode{}.
|
||||
|
||||
%%% public api
|
||||
|
||||
-spec start_link(Index :: non_neg_integer()) -> gen_server:start_ret().
|
||||
start_link(Index) ->
|
||||
gen_server:start_link(?MODULE, [Index], []).
|
||||
|
||||
-spec get(VNode :: gen_server:server_ref(), Key :: term()) -> {ok, Value :: term()} | none.
|
||||
get(VNode, Key) ->
|
||||
gen_server:call(VNode, {get, Key}).
|
||||
|
||||
-spec put(VNode :: gen_server:server_ref(), Key :: term(), Value :: term()) -> ok.
|
||||
put(VNode, Key, Value) ->
|
||||
gen_server:cast(VNode, {put, Key, Value}).
|
||||
|
||||
%%% gen_server callbacks
|
||||
|
||||
-spec init([Index :: non_neg_integer()]) -> {ok, state()}.
|
||||
init([Index]) ->
|
||||
{ok, #kv_vnode{index = Index, table = ets:new(?MODULE, [set, private])}}.
|
||||
|
||||
handle_call({get, Key}, _From, #kv_vnode{table = Table} = State) ->
|
||||
Reply =
|
||||
case ets:lookup(Table, Key) of
|
||||
[{_, Value}] -> {ok, Value};
|
||||
[] -> none
|
||||
end,
|
||||
{reply, Reply, State}.
|
||||
|
||||
handle_cast({put, Key, Value}, #kv_vnode{table = Table} = State) ->
|
||||
ets:insert(Table, {Key, Value}),
|
||||
{noreply, State}.
|
44
apps/kv/src/kv_vnode_manager.erl
Normal file
44
apps/kv/src/kv_vnode_manager.erl
Normal file
|
@ -0,0 +1,44 @@
|
|||
-module(kv_vnode_manager).
|
||||
|
||||
-behaviour(gen_server).
|
||||
|
||||
-export([
|
||||
start_link/0,
|
||||
get_vnode/1
|
||||
]).
|
||||
|
||||
%%% gen_server callbacks
|
||||
-export([init/1, handle_call/3, handle_cast/2]).
|
||||
|
||||
-record(kv_vnode_manager, {table :: ets:table()}).
|
||||
|
||||
-type state() :: #kv_vnode_manager{}.
|
||||
|
||||
%%% public api
|
||||
|
||||
start_link() ->
|
||||
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||
|
||||
get_vnode(Index) ->
|
||||
gen_server:call(?MODULE, {get_vnode, Index}).
|
||||
|
||||
%%% gen_server callbacks
|
||||
|
||||
-spec init([]) -> {ok, state()}.
|
||||
init([]) ->
|
||||
{ok, #kv_vnode_manager{table = ets:new(?MODULE, [set])}}.
|
||||
|
||||
handle_call({get_vnode, Index}, _From, State) ->
|
||||
Table = State#kv_vnode_manager.table,
|
||||
Reply =
|
||||
case ets:lookup(Table, Index) of
|
||||
[{_, Pid}] ->
|
||||
{ok, Pid};
|
||||
[] ->
|
||||
{ok, Pid} = kv_vnode_sup:start_vnode(Index),
|
||||
ets:insert(Table, {Index, Pid}),
|
||||
{ok, Pid}
|
||||
end,
|
||||
{reply, Reply, State}.
|
||||
|
||||
handle_cast(_, _) -> error(not_implemented).
|
35
apps/kv/src/kv_vnode_sup.erl
Normal file
35
apps/kv/src/kv_vnode_sup.erl
Normal file
|
@ -0,0 +1,35 @@
|
|||
-module(kv_vnode_sup).
|
||||
|
||||
-behaviour(supervisor).
|
||||
|
||||
-export([start_link/0, start_vnode/1]).
|
||||
|
||||
%%% supervisor callbacks
|
||||
-export([init/1]).
|
||||
|
||||
%%% public api
|
||||
|
||||
start_link() ->
|
||||
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
|
||||
|
||||
-spec start_vnode(Index :: non_neg_integer()) -> supervisor:startchild_ret().
|
||||
start_vnode(Index) ->
|
||||
supervisor:start_child(?MODULE, [Index]).
|
||||
|
||||
%%% supervisor callbacks
|
||||
|
||||
init([]) ->
|
||||
SupFlags = #{
|
||||
strategy => simple_one_for_one,
|
||||
intensity => 0,
|
||||
period => 1
|
||||
},
|
||||
ChildSpec = #{
|
||||
id => undefined,
|
||||
start => {kv_vnode, start_link, []},
|
||||
restart => temporary,
|
||||
type => worker
|
||||
},
|
||||
{ok, {SupFlags, [ChildSpec]}}.
|
||||
|
||||
%%% internal functions
|
1
rebar.lock
Normal file
1
rebar.lock
Normal file
|
@ -0,0 +1 @@
|
|||
[].
|
Loading…
Add table
Reference in a new issue