diff options
Diffstat (limited to 'p11p-daemon/src/p11p_remote_manager.erl')
-rw-r--r-- | p11p-daemon/src/p11p_remote_manager.erl | 81 |
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))]). |