erlang各种有用的函数包括一些有用nif封装,还有一些性能测试case。
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

145 行
4.8 KiB

-module(server_control_main).
-export([start/0]).
-define(RPC_TIMEOUT, infinity).
commands_desc() ->
[{"stop", "停止游戏服务器进程"},
{"stop_all", "停止游戏集群进程"},
{"stop_app", "关闭server application"},
{"start_app", "打开server application"},
{"cluster_status", "集群状态"}].
opt_spec_list() ->
Node = case get(nodename) of
undefined ->
throw(not_nodename);
V ->
V
end,
[
{help, $h, "help", undefined, "显示帮助,然后退出"},
{node, undefined, "node", {atom, Node}, "管理节点"}
].
usage() ->
getopt:usage(opt_spec_list(), "server_ctl", "<command> [<args>]", commands_desc()),
err_misc:quit(1).
parse_arguments(CmdLine) ->
case getopt:parse(opt_spec_list(), CmdLine) of
{ok, {Opts, [Command | Args]}} ->
{ok, {list_to_atom(Command), Opts, Args}};
{ok, {_Opts, []}} ->
no_command;
Error ->
io:format("Error ~p~n", [Error]),
no_command
end.
start() ->
{ok, [[NodeStr|_]|_]} = init:get_argument(nodename),
put(nodename, list_to_atom(NodeStr)),
{Command, Opts, Args} =
case parse_arguments(init:get_plain_arguments()) of
{ok, Res} ->
Res;
no_command ->
usage()
end,
Node = proplists:get_value(node, Opts),
net_adm:ping(Node),
timer:sleep(1000), %% wait auto find node
%% The reason we don't use a try/catch here is that rpc:call turns
%% thrown errors into normal return values
% io:format("Opts ~p~n", [Opts]),
case catch action(Command, Node, Args, Opts) of
ok ->
io:format("done.~n", []),
quit(0);
{ok, Info} ->
io:format("done (~p).~n", [Info]),
quit(0);
Other ->
io:format("other result ~p~n", [Other]),
quit(2)
end.
action(info, Node, _Args, _Opts) ->
io:format("System info for Node ~p~n", [Node]),
Res = call(Node, {main, get_info, []}),
io:format( " ~n Scheduler id: ~p
~n Num scheduler: ~p
~n Process count: ~p
~n Process limit: ~p
~n Memory used by erlang processes: ~p
~n Memory allocated by erlang processes: ~p
~n The total amount of memory allocated: ~p
~n",
Res),
ok;
action(backup, Node, _Args, _Opts) ->
case call(Node, {app_misc, backup, []}) of
{error, Msg} ->
io:format("~s~n", [Msg]);
{ok, FileName} ->
io:format("backup file:~s~n", [FileName]),
io:format("backup file to remote ......~n", []),
Result = os:cmd("bash copy_to_remote.sh " ++ FileName),
io:format("~s~n", [Result])
end,
ok;
action(pause_accept, Node, _Args, _Opts) ->
io:format("Pause accept new client ~p~n", [Node]),
call(Node, {app_misc, pause_accept, []}),
ok;
action(resume_accept, Node, _Args, _Opts) ->
io:format("Resume accept new client ~p~n", [Node]),
call(Node, {app_misc, resume_accept, []}),
ok;
action(accept_state, Node, _Args, _Opts) ->
Res = call(Node, {app_misc, can_accept_new, []}),
io:format("Node ~p accept state:~p~n ", [Node, Res]),
ok;
action(reload, Node, _Args, _Opts) ->
io:format("Reloading node ~p~n", [Node]),
call(Node, {main, reload, []});
action(stop_all, MasterNode, _Args, _Opts) ->
io:format("Stopping and halting all node~n", []),
PidMRefs = [{spawn_monitor(fun() ->
call(Node, {main, stop_and_halt, [5]})
end), Node}
|| Node <- nodes() -- [MasterNode]],
[receive
{'DOWN', MRef, process, _, normal} ->
ok;
{'DOWN', MRef, process, _, Reason} ->
io:format("Node ~p Error, Reason ~p", [Node, Reason])
end || {{_Pid, MRef}, Node} <- PidMRefs],
call(MasterNode, {main, stop_and_halt, [5]}),
ok;
action(stop, Node, _Args, _Opts) ->
io:format("Stopping and halting node ~p~n", [Node]),
call(Node, {main, stop_and_halt, [5]});
action(Command, _Node, Args, Opts) ->
io:format("Command: ~p Args: ~p Opts: ~p~n", [Command, Args, Opts]),
invalid_command.
call(Node, {Mod, Fun, Args}) ->
%%rpc_call(Node, Mod, Fun, lists:map(fun list_to_binary/1, Args)).
rpc_call(Node, Mod, Fun, Args).
rpc_call(Node, Mod, Fun, Args) ->
rpc:call(Node, Mod, Fun, Args, ?RPC_TIMEOUT).
quit(Status) ->
case os:type() of
{unix, _} ->
halt(Status);
{win32, _} ->
init:stop(Status),
receive
after infinity ->
ok
end
end.