|
|
- -module(agAgencyPoolMgrIns).
- -include("agHttpCli.hrl").
-
- -compile(inline).
- -compile({inline_size, 128}).
-
-
- -export([
- startPool/2
- , startPool/3
- , stopPool/1
- , getOneAgency/1
-
- %% genExm API
- , init/1
- , handleMsg/2
- , terminate/2
- ]).
-
- %% k-v缓存表
- -define(ETS_AG_Pool, ets_ag_Pool).
- -define(ETS_AG_Agency, ets_ag_Agency).
-
- -spec init(Args :: term()) -> ok.
- init(_Args) ->
- ets:new(?ETS_AG_Pool, [named_table, set, protected]),
- ets:new(?ETS_AG_Agency, [named_table, set, protected]),
- agKvsToBeam:load(?agBeamPool, []),
- agKvsToBeam:load(?agBeamAgency, []),
- {ok, undefined}.
-
- handleMsg({'$gen_call', From, {miStartPool, PoolName, DbCfgs, AgencyOpts}}, State) ->
- dealStart(PoolName, DbCfgs, AgencyOpts),
- gen_server:reply(From, ok),
- {ok, State};
- handleMsg({'$gen_call', From, {miStopPool, Name}}, State) ->
- delaStop(Name),
- gen_server:reply(From, ok),
- {ok, State};
- handleMsg(_Msg, State) ->
- ?WARN(?MODULE, "receive unexpected msg: ~p", [_Msg]),
- {ok, State}.
-
- terminate(_Reason, _State) ->
- ets:delete_all_objects(?ETS_AG_Pool),
- ets:delete_all_objects(?ETS_AG_Agency),
- agKvsToBeam:load(?agBeamPool, []),
- agKvsToBeam:load(?agBeamAgency, []),
- ok.
-
- -spec startPool(poolName(), dbCfgs()) -> ok | {error, pool_name_used}.
- startPool(PoolName, DbCfgs) ->
- startPool(PoolName, DbCfgs, []).
-
- -spec startPool(poolName(), dbCfgs(), agencyCfgs()) -> ok | {error, pool_name_used}.
- startPool(PoolName, DbCfgs, AgencyCfgs) ->
- case ?agBeamPool:get(PoolName) of
- undefined ->
- gen_server:call(?agAgencyPoolMgr, {miStartPool, PoolName, DbCfgs, AgencyCfgs});
- _ ->
- {error, pool_name_used}
- end.
-
- -spec stopPool(poolName()) -> ok | {error, pool_not_started}.
- stopPool(PoolName) ->
- case ?agBeamPool:get(PoolName) of
- undefined ->
- {error, pool_not_started};
- _ ->
- gen_server:call(?agAgencyPoolMgr, {miStopPool, PoolName})
-
- end.
-
- dealStart(PoolName, DbCfgs, AgencyCfgs) ->
- #dbOpts{poolSize = PoolSize, protocol = Protocol} = DbOpts = agMiscUtils:dbOpts(DbCfgs),
- AgencyOpts = agMiscUtils:agencyOpts(AgencyCfgs),
- cacheAddPool(PoolName, DbOpts),
- startChildren(PoolName, Protocol, PoolSize, AgencyOpts),
- cacheAddAgency(PoolName, PoolSize),
- case persistent_term:get(PoolName, undefined) of
- undefined ->
- IndexRef = atomics:new(1, [{signed, false}]),
- persistent_term:put(PoolName, IndexRef);
- _ ->
- ignore
- end,
- ok.
-
- delaStop(PoolName) ->
- case ?agBeamPool:get(PoolName) of
- undefined ->
- {error, pool_not_started};
- #dbOpts{poolSize = PoolSize} ->
- stopChildren(agencyNames(PoolName, PoolSize)),
- cacheDelPool(PoolName),
- cacheDelAgency(PoolName),
- ok
- end.
-
- agencyName(PoolName, Index) ->
- list_to_atom(atom_to_list(PoolName) ++ "_" ++ integer_to_list(Index)).
-
- agencyNames(PoolName, PoolSize) ->
- [agencyName(PoolName, N) || N <- lists:seq(1, PoolSize)].
-
- agencyMod(tcp) ->
- agTcpAgencyExm;
- agencyMod(ssl) ->
- agSslAgencyExm;
- agencyMod(_) ->
- agTcpAgencyExm.
-
- agencySpec(ServerMod, ServerName, Args) ->
- %% TODO 下面spawn_opt 参数需要调优
- StartFunc = {ServerMod, start_link, [ServerName, Args, [{min_heap_size, 5000}, {min_bin_vheap_size, 100000}, {fullsweep_after, 500}]]},
- {ServerName, StartFunc, transient, infinity, worker, [ServerMod]}.
-
- -spec startChildren(atom(), protocol(), poolSize(), agencyOpts()) -> ok.
- startChildren(PoolName, Protocol, PoolSize, AgencyOpts) ->
- AgencyMod = agencyMod(Protocol),
- AgencyNames = agencyNames(PoolName, PoolSize),
- AgencySpecs = [agencySpec(AgencyMod, AgencyName, {PoolName, AgencyName, AgencyOpts}) || AgencyName <- AgencyNames],
- [supervisor:start_child(agAgencyPool_sup, AgencySpec) || AgencySpec <- AgencySpecs],
- ok.
-
- stopChildren([AgencyName | T]) ->
- ok = supervisor:terminate_child(agAgencyPool_sup, AgencyName),
- ok = supervisor:delete_child(agAgencyPool_sup, AgencyName),
- stopChildren(T);
- stopChildren([]) ->
- ok.
-
- cacheAddPool(Key, Value) ->
- ets:insert(?ETS_AG_Pool, {Key, Value}),
- KVS = ets:tab2list(?ETS_AG_Pool),
- agKvsToBeam:load(?agBeamPool, KVS),
- ok.
-
- cacheDelPool(Key) ->
- ets:delete(?ETS_AG_Pool, Key),
- KVS = ets:tab2list(?ETS_AG_Pool),
- agKvsToBeam:load(?agBeamPool, KVS),
- ok.
-
- cacheAddAgency(PoolName, PoolSize) ->
- NameList = [{{PoolName, N}, agencyName(PoolName, N)} || N <- lists:seq(1, PoolSize)],
- ets:insert(?ETS_AG_Agency, NameList),
- KVS = ets:tab2list(?ETS_AG_Agency),
- agKvsToBeam:load(?agBeamAgency, KVS),
- ok.
-
- cacheDelAgency(PoolName) ->
- ets:match_delete(?ETS_AG_Agency, {{PoolName, '_'}, '_'}),
- KVS = ets:tab2list(?ETS_AG_Agency),
- agKvsToBeam:load(?agBeamAgency, KVS),
- ok.
-
- -spec getOneAgency(atom()) -> atom() | {error, term()}.
- getOneAgency(PoolName) ->
- case ?agBeamPool:get(PoolName) of
- undefined ->
- {error, pool_not_found};
- #dbOpts{poolSize = PoolSize} ->
- Ref = persistent_term:get(PoolName),
- AgencyIdx = atomics:add_get(Ref, 1, 1),
- case AgencyIdx >= PoolSize of
- true ->
- atomics:put(Ref, 1, 0),
- ?agBeamAgency:get({PoolName, PoolSize});
- _ ->
- ?agBeamAgency:get({PoolName, AgencyIdx})
- end
- end.
|