summaryrefslogtreecommitdiff
path: root/p11p-daemon/src/p11p_remote_manager.erl
diff options
context:
space:
mode:
Diffstat (limited to 'p11p-daemon/src/p11p_remote_manager.erl')
-rw-r--r--p11p-daemon/src/p11p_remote_manager.erl81
1 files changed, 61 insertions, 20 deletions
diff --git a/p11p-daemon/src/p11p_remote_manager.erl b/p11p-daemon/src/p11p_remote_manager.erl
index 5fe5bc7..23c69a7 100644
--- a/p11p-daemon/src/p11p_remote_manager.erl
+++ b/p11p-daemon/src/p11p_remote_manager.erl
@@ -36,12 +36,14 @@
tokname :: string(),
servid :: atom(),
modpath :: string(),
+ balance :: integer(),
pid :: pid() | undefined
}).
-record(token, {
- remotes :: [#remote{}], % Active remote in hd().
- replay = <<>> :: binary() % FIXME: seems unfeasable, remove
+ mode :: p11p_config:token_mode_t(),
+ balance_count :: integer(),
+ remotes :: [#remote{}] % Active remote in hd().
}).
-record(state, {
@@ -68,13 +70,27 @@ init([]) ->
handle_call({remote_for_token, TokName}, _From, #state{tokens = Tokens} = State) ->
#{TokName := Token} = Tokens,
- Remotes = Token#token.remotes,
+ lager:debug("all remotes: ~p", [Token#token.remotes]),
+ {Remotes, NewBC} =
+ case Token#token.balance_count of
+ 0 ->
+ lager:debug("~p: balancing: next remote", [self()]),
+ R0 = rotate_remotes(Token#token.remotes),
+ R = hd(R0),
+ {R0, R#remote.balance - 1};
+ N when N > 0 ->
+ lager:debug("~p: balancing: ~B more invocations", [self(), N]),
+ {Token#token.remotes, N - 1};
+ -1 ->
+ {Token#token.remotes, -1}
+ end,
#remote{tokname = TokName, servid = ServId, modpath = ModPath, pid = Pid} = Remote = hd(Remotes),
case Pid of
undefined ->
{ok, NewPid} = p11p_remote:start_link(ServId, TokName, ModPath),
NewRemote = Remote#remote{pid = NewPid},
- NewToken = Token#token{remotes = [NewRemote | tl(Remotes)]},
+ NewToken = Token#token{remotes = [NewRemote | tl(Remotes)],
+ balance_count = NewBC},
NewState = State#state{tokens = Tokens#{TokName := NewToken}},
{reply, NewPid, NewState};
_ ->
@@ -135,23 +151,48 @@ init_tokens([], Acc)->
lager:debug("~p: created tokens from config: ~p", [self(), Acc]),
Acc;
init_tokens([H|T], Acc)->
- TokName = p11p_config:nameof(H),
- init_tokens(T, Acc#{TokName => new_token(TokName, H)}).
-
-new_token(TokName, ConfToken) ->
- #token{remotes = remotes(TokName, p11p_config:modules_for_token(p11p_config:nameof(ConfToken)))}.
-
-remotes(TokName, ConfModules) ->
- remotes(TokName, ConfModules, []).
-remotes(_, [], Acc) ->
+ init_tokens(T, Acc#{p11p_config:nameof(H) => new_token(H)}).
+
+new_token(Conf) ->
+ Name = p11p_config:nameof(Conf),
+ Mode = p11p_config:token_mode(Name),
+ Remotes = remotes(Name,
+ p11p_config:modules_for_token(Name),
+ Mode),
+ R0 = hd(Remotes),
+ #token{
+ mode = p11p_config:token_mode(Name),
+ balance_count = R0#remote.balance,
+ remotes = Remotes
+ }.
+
+remotes(TokName, ConfModules, ConfMode) ->
+ remotes(TokName, ConfModules, ConfMode, []).
+remotes(_, [], _, Acc) ->
Acc;
-remotes(TokName, [H|T], Acc) ->
+remotes(TokName, [H|T], ConfMode, Acc) ->
ModName = p11p_config:nameof(H),
ServName = "p11p_remote:" ++ TokName ++ ":" ++ ModName,
ModPath = p11p_config:module_path(H),
- remotes(TokName, T, [#remote{
- tokname = TokName,
- servid = list_to_atom(ServName),
- modpath = ModPath,
- pid = undefined
- } | Acc]).
+ remotes(TokName, T, ConfMode, [#remote{
+ tokname = TokName,
+ servid = list_to_atom(ServName),
+ modpath = ModPath,
+ balance = balance(ConfMode, length(T) + 1)
+ }
+ | Acc]).
+
+-spec balance(p11p_config:token_mode_t(), non_neg_integer()) -> integer().
+balance({balance, Ratios}, N) ->
+ lists:nth(N, Ratios);
+balance(_, _) ->
+ -1.
+
+%% -spec balance_count(p11p_config:token_mode_t()) -> integer().
+%% balance_count(#token{mode = {balance, _}, balance_count = C}) ->
+%% C - 1;
+%% balance_count(_) ->
+%% -1.
+
+rotate_remotes(L) ->
+ lists:reverse([hd(L) | lists:reverse(tl(L))]).