erlang各种有用的函数包括一些有用nif封装,还有一些性能测试case。
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 
 
 

211 satır
6.9 KiB

%%----------------------------------------------------
%% Erlang模块热更新到所有线路(包括server的回调函数,如果对state有影响时慎用)
%%
%% 检查:u:c() %% 列出前5分钟内编译过的文件
%% u:c(N) %% 列出前N分钟内编译过的文件
%%
%% 更新:u:u() %% 更新前5分钟内编译过的文件
%% u:u(N) %% 更新前N分钟内编译过的文件
%% u:u([mod_xx, ...]) %% 指定模块(不带后缀名)
%% u:u(m) %% 编译并加载文件
%%
%% Tips: u - update, c - check
%%
%% @author rolong@vip.qq.com
%%----------------------------------------------------
-module(u).
-compile(export_all).
-include_lib("kernel/include/file.hrl").
c() ->
c(5).
c(S) when is_integer(S) ->
c:cd("../ebin"),
case file:list_dir(".") of
{ok, FileList} ->
Files = get_new_file(FileList, S * 60),
info("---------check modules---------~n~w~n=========check modules=========", [Files]);
Any -> info("Error Dir: ~w", [Any])
end;
c([S]) when is_atom(S) ->
S1 = tool:to_integer(tool:to_list(S)),
case is_integer(S1) of
true ->
c:cd("../ebin"),
case file:list_dir(".") of
{ok, FileList} ->
Files = get_new_file(FileList, S * 60),
info("---------check modules---------~n~w~n=========check modules=========", [Files]);
Any -> info("Error Dir: ~w", [Any])
end;
_ ->
info("ERROR======> Badarg ~p/~p ~n", [S, S1])
end;
c(S) -> info("ERROR======> Badarg ~p ~n", [S]).
admin() ->
spawn(fun() -> u(m) end),
ok.
u() ->
u(5).
u(m) ->
StartTime = util:unixtime(),
info("----------makes----------", []),
c:cd("../"),
make:all(),
c:cd("ebin"),
EndTime = util:unixtime(),
Time = EndTime - StartTime,
info("Make Time : ~w s", [Time]),
u(Time / 60);
u(S) when is_number(S) ->
case file:list_dir(".") of
{ok, FileList} ->
Files = get_new_file(FileList, util:ceil(S * 60) + 3),
load(Files);
%% AllZone = mod_node_interface:server_list(),
%% info("---------modules---------~n~w~n----------nodes----------", [Files]),
%% loads(AllZone, Files);
Any -> info("Error Dir: ~w", [Any])
end;
u(Files) when is_list(Files) ->
load(Files);
%% AllZone = mod_node_interface:server_list(),
%% info("---------modules---------~n~w~n----------nodes----------", [Files]),
%% loads(AllZone, Files);
u(_) -> info("ERROR======> Badarg", []).
%% m(['src/data/*','src/lib/lib_goods.erl'])
m(Files) when is_list(Files) ->
StartTime = util:unixtime(),
info("----------makes----------~n~w~n", [Files]),
c:cd("../"),
Res = make:files(Files, [debug_info, {i, "include"}, {outdir, "ebin"}]),
c:cd("ebin"),
EndTime = util:unixtime(),
Time = EndTime - StartTime,
info("Make Time : ~w s", [Time]),
Res.
info(V) ->
info(V, []).
info(V, P) ->
io:format(V ++ "~n", P).
%% 更新到所有线路,暂时处理单节点的情况
%% loads([], _Files) -> ok;
%% loads([H | T], Files) ->
%% info("[~w]", [H#t_server_node.node]),
%% rpc:cast(H#t_server_node.node, u, load, [Files]),
%% loads(T, Files).
get_new_file(Files, S) ->
get_new_file(Files, S, []).
get_new_file([], _S, Result) -> Result;
get_new_file([H | T], S, Result) ->
NewResult = case string:tokens(H, ".") of
[Left, Right] when Right =:= "beam" ->
case file:read_file_info(H) of
{ok, FileInfo} ->
Now = calendar:local_time(),
case calendar:time_difference(FileInfo#file_info.mtime, Now) of
{Days, Times} ->
Seconds = calendar:time_to_seconds(Times),
case Days =:= 0 andalso Seconds < S of
true ->
FileName = list_to_atom(Left),
[FileName | Result];
false -> Result
end;
_ -> Result
end;
_ -> Result
end;
_ -> Result
end,
get_new_file(T, S, NewResult).
load([]) -> ok;
load([FileName | T]) ->
c:l(FileName),
info("loaded: ~w", [FileName]),
load(T).
% case code:soft_purge(FileName) of
% true ->
% case code:load_file(FileName) of
% {module, _} ->
% info("loaded: ~w", [FileName]),
% ok;
% %% info("loaded: ~w", [FileName]);
% {error, What} -> info("ERROR======> loading: ~w (~w)", [FileName, What])
% end;
% false -> info("ERROR======> Processes lingering : ~w [zone ~w] ", [FileName, srv_kernel:zone_id()])
% end,
% load(T).
a() ->
c(),
u().
%% @spec hotswap() -> ok
%% @doc 用于远程热更新
hotswap(NodeArg) ->
Node = util_data:to_atom(hd(NodeArg)),
net_adm:ping(Node),
rpc:call(Node, ?MODULE, do_hotswap, []).
do_hotswap() ->
CommandFile = "../../hotswap/hotswap_command.txt",
case filelib:is_file(CommandFile) andalso filelib:file_size(CommandFile) > 2 of
true ->
{{Y, M, D}, {H, I, S}} = erlang:localtime(),
TimeString = io_lib:format("[~w-~w-~w ~w:~w:~w]", [Y, M, D, H, I, S]),
try
info("===> command running ..."),
case file:open(CommandFile, read) of
{ok, IoDevice} ->
case file:eval(CommandFile) of
ok -> info("Update Time: ~s", [TimeString]);
{error, EvalErr} -> info("~s Eval Error:~w", [TimeString, EvalErr])
end,
info("command:"),
ResultData = parse(IoDevice, <<>>),
case byte_size(ResultData) < 5 of
true -> info("Empty Command (<5byte): ~s", [TimeString]);
false -> info("=> ~s", [ResultData])
end,
file:close(IoDevice),
file:delete(CommandFile);
{error, OpenErr} ->
info("~s Open Error:~w\n", [TimeString, OpenErr])
end
catch T : X ->
info("~s Error: ~w : ~w\nUpdate Server Is Stopped!\n", [TimeString, T, X])
end;
false -> ignore
end,
ok.
parse(IoDevice, D) ->
case io:get_line(IoDevice, '') of
eof ->
%% info("\n--- DONE ---"),
D;
Data ->
%% io:format("=> ~s", [Data]),
parse(IoDevice, list_to_binary([D, Data]))
end.
%% @doc 保证正确的工作路径
%% @spec make_sure_working_dir() -> any().
make_sure_working_dir() ->
Cwd = config:get_cwd(),
case file:get_cwd() == Cwd of
true ->
skip;
_ ->
c:cd(Cwd)
end.