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,
|
intensity => 0,
|
||||||
period => 1
|
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}}.
|
{ok, {SupFlags, ChildSpecs}}.
|
||||||
|
|
||||||
%%% internal functions
|
%%% 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