Browse Source

部分代码整理

master
SisMaker 4 years ago
parent
commit
a7bb276450
3 changed files with 55 additions and 262 deletions
  1. +53
    -81
      src/hotUpdate/reloader.erl
  2. +0
    -165
      src/hotUpdate/reloader1.erl
  3. +2
    -16
      src/measure/utProf.erl

+ 53
- 81
src/hotUpdate/reloader.erl View File

@ -1,45 +1,18 @@
%% The MIT License (MIT)
%%
%% Copyright (c) 2014-2024
%% Savin Max <mafei.198@gmail.com>
%%
%% Permission is hereby granted, free of charge, to any person obtaining a copy
%% of this software and associated documentation files (the "Software"), to deal
%% in the Software without restriction, including without limitation the rights
%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
%% copies of the Software, and to permit persons to whom the Software is
%% furnished to do so, subject to the following conditions:
%%
%% The above copyright notice and this permission notice shall be included in all
%% copies or substantial portions of the Software.
%%
%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
%% SOFTWARE.
%%
%% @doc Erlang module for automatically reloading modified modules
%% during development.
-module(reloader).
-include_lib("kernel/include/file.hrl").
-behaviour(gen_server).
-export([start/0, start_link/0]).
-export([register_after_reload/1]).
-export([stop/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-export([all_changed/0]).
-export([is_changed/1]).
-export([reload_modules/1]).
-export([reload_all/0]).
-record(state, {last,
tref,
after_reload_callback}).
-record(state, {last, tref}).
%% External API
@ -58,52 +31,58 @@ start_link() ->
stop() ->
gen_server:call(?MODULE, stop).
register_after_reload(Fun) ->
gen_server:call(?MODULE, {register_after_reload, Fun}).
%% gen_server callbacks
%% -define(RERODER_CHECK_TIME, 5000).
%% @spec init([]) -> {ok, State}
%% @doc gen_server init, opens the server in an initial state.
init([]) ->
{ok, TRef} = timer:send_interval(timer:seconds(1), doit),
{ok, #state{last = stamp(), tref = TRef}}.
%% {ok, TRef} = timer:send_interval(timer:seconds(1), doit),
%% TimerRef = erlang:send_after(?RERODER_CHECK_TIME, self(), doit),
%% tref = TimerRef}}.
{ok, #state{last = stamp()}}.
%% @spec handle_call(Args, From, State) -> tuple()
%% @doc gen_server callback.
handle_call(stop, _From, State) ->
{stop, shutdown, stopped, State};
handle_call({register_after_reload, Fun}, _From, State) ->
{reply, ok, State#state{after_reload_callback = Fun}};
handle_call(_Req, _From, State) ->
{reply, {error, badrequest}, State}.
%% @spec handle_cast(Cast, State) -> tuple()
%% @doc gen_server callback.
handle_cast(_Req, State) ->
{noreply, State}.
%% @spec handle_info(Info, State) -> tuple()
%% @doc gen_server callback.
handle_info(doit, #state{after_reload_callback = Fun} = State) ->
handle_cast(doit, State) ->
error_logger:info_msg("reloader do reload ... ~n", []),
%% TimerRef = erlang:send_after(?RERODER_CHECK_TIME, self(), doit),
Now = stamp(),
ReloadedModules = doit(State#state.last, Now),
if
ReloadedModules =/= [] andalso Fun =/= undefined ->
Fun(ReloadedModules);
true -> ok
end,
{noreply, State#state{last = Now}};
try
_ = doit(State#state.last, Now),
%% tref = TimerRef
error_logger:info_msg("reloader done ... ~n", []),
{noreply, State#state{last = Now}}
catch
_:R ->
error_logger:error_msg(
"reload failed R:~w Stack:~p~n", [R, erlang:get_stacktrace()]),
%% reloader failed, no state update
{noreply, State}
end;
handle_cast(_Req, State) ->
{noreply, State}.
handle_info(_Info, State) ->
{noreply, State}.
%% @spec terminate(Reason, State) -> ok
%% @doc gen_server termination callback.
terminate(_Reason, State) ->
{ok, cancel} = timer:cancel(State#state.tref),
terminate(_Reason, _State) ->
%% erlang:cancel_timer(State#state.tref),
%% {ok, cancel} = timer:cancel(State#state.tref),
ok.
%% @spec code_change(_OldVsn, State, _Extra) -> State
%% @doc gen_server code_change callback (trivial).
code_change(_Vsn, State, _Extra) ->
@ -120,6 +99,10 @@ reload_modules(Modules) ->
all_changed() ->
[M || {M, Fn} <- code:all_loaded(), is_list(Fn), is_changed(M)].
%% @spec reload_all() -> [atom()]
reload_all() ->
gen_server:cast(?MODULE, doit).
%% @spec is_changed(atom()) -> boolean()
%% @doc true if the loaded module is a beam with a vsn attribute
%% and does not match the on-disk beam file, returns false otherwise.
@ -141,46 +124,35 @@ module_vsn(L) when is_list(L) ->
Vsn.
doit(From, To) ->
lists:foldl(fun({Module, Filename}, Acc) ->
case is_list(Filename) of
false -> Acc;
true ->
case file:read_file_info(Filename) of
{ok, #file_info{mtime = Mtime}} when Mtime >= From, Mtime < To ->
case reload(Module) of
error -> Acc;
_ -> [Module | Acc]
end;
{ok, _} ->
% unmodified;
Acc;
{error, enoent} ->
%% The Erlang compiler deletes existing .beam files if
%% recompiling fails. Maybe it's worth spitting out a
%% warning here, but I'd want to limit it to just once.
% gone;
Acc;
{error, Reason} ->
io:format("Error reading ~s's file info: ~p~n",
[Filename, Reason]),
% error
Acc
end
end
end, [], code:all_loaded()).
[case file:read_file_info(Filename) of
{ok, #file_info{mtime = Mtime}} when Mtime >= From, Mtime < To ->
reload(Module);
{ok, _} ->
unmodified;
{error, enoent} ->
%% The Erlang compiler deletes existing .beam files if
%% recompiling fails. Maybe it's worth spitting out a
%% warning here, but I'd want to limit it to just once.
gone;
{error, Reason} ->
error_logger:error_msg("Error reading ~s's file info: ~p~n",
[Filename, Reason]),
error
end || {Module, Filename} <- code:all_loaded(), is_list(Filename)].
reload(Module) ->
io:format("Reloading ~p ...", [Module]),
error_logger:info_msg("Reloading ~p ...", [Module]),
code:purge(Module),
case code:load_file(Module) of
{module, Module} ->
io:format(" ok.~n"),
error_logger:info_msg("reload ~w ok.~n", [Module]),
reload;
{error, Reason} ->
io:format(" fail: ~p.~n", [Reason]),
error_logger:error_msg("reload fail: ~p.~n", [Reason]),
error
end.
stamp() ->
erlang:localtime().

+ 0
- 165
src/hotUpdate/reloader1.erl View File

@ -1,165 +0,0 @@
%% @copyright 2007 Mochi Media, Inc.
%% @author Matthew Dempsky <matthew@mochimedia.com>
%%
%% @doc Erlang module for automatically reloading modified modules
%% during development.
-module(reloader1).
-author("Matthew Dempsky <matthew@mochimedia.com>").
-include_lib("kernel/include/file.hrl").
-behaviour(gen_server).
-export([start/0, start_link/0]).
-export([stop/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-export([all_changed/0]).
-export([is_changed/1]).
-export([reload_modules/1]).
-export([reload_all/0]).
-record(state, {last, tref}).
%% External API
%% @spec start() -> ServerRet
%% @doc Start the reloader.
start() ->
gen_server:start({local, ?MODULE}, ?MODULE, [], []).
%% @spec start_link() -> ServerRet
%% @doc Start the reloader.
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
%% @spec stop() -> ok
%% @doc Stop the reloader.
stop() ->
gen_server:call(?MODULE, stop).
%% gen_server callbacks
%% -define(RERODER_CHECK_TIME, 5000).
%% @spec init([]) -> {ok, State}
%% @doc gen_server init, opens the server in an initial state.
init([]) ->
%% {ok, TRef} = timer:send_interval(timer:seconds(1), doit),
%% TimerRef = erlang:send_after(?RERODER_CHECK_TIME, self(), doit),
%% tref = TimerRef}}.
{ok, #state{last = stamp()}}.
%% @spec handle_call(Args, From, State) -> tuple()
%% @doc gen_server callback.
handle_call(stop, _From, State) ->
{stop, shutdown, stopped, State};
handle_call(_Req, _From, State) ->
{reply, {error, badrequest}, State}.
%% @spec handle_cast(Cast, State) -> tuple()
%% @doc gen_server callback.
%% @spec handle_info(Info, State) -> tuple()
%% @doc gen_server callback.
handle_cast(doit, State) ->
error_logger:info_msg("reloader do reload ... ~n", []),
%% TimerRef = erlang:send_after(?RERODER_CHECK_TIME, self(), doit),
Now = stamp(),
try
_ = doit(State#state.last, Now),
%% tref = TimerRef
error_logger:info_msg("reloader done ... ~n", []),
{noreply, State#state{last = Now}}
catch
_:R ->
error_logger:error_msg(
"reload failed R:~w Stack:~p~n", [R, erlang:get_stacktrace()]),
%% reloader failed, no state update
{noreply, State}
end;
handle_cast(_Req, State) ->
{noreply, State}.
handle_info(_Info, State) ->
{noreply, State}.
%% @spec terminate(Reason, State) -> ok
%% @doc gen_server termination callback.
terminate(_Reason, _State) ->
%% erlang:cancel_timer(State#state.tref),
%% {ok, cancel} = timer:cancel(State#state.tref),
ok.
%% @spec code_change(_OldVsn, State, _Extra) -> State
%% @doc gen_server code_change callback (trivial).
code_change(_Vsn, State, _Extra) ->
{ok, State}.
%% @spec reload_modules([atom()]) -> [{module, atom()} | {error, term()}]
%% @doc code:purge/1 and code:load_file/1 the given list of modules in order,
%% return the results of code:load_file/1.
reload_modules(Modules) ->
[begin code:purge(M), code:load_file(M) end || M <- Modules].
%% @spec all_changed() -> [atom()]
%% @doc Return a list of beam modules that have changed.
all_changed() ->
[M || {M, Fn} <- code:all_loaded(), is_list(Fn), is_changed(M)].
%% @spec reload_all() -> [atom()]
reload_all() ->
gen_server:cast(?MODULE, doit).
%% @spec is_changed(atom()) -> boolean()
%% @doc true if the loaded module is a beam with a vsn attribute
%% and does not match the on-disk beam file, returns false otherwise.
is_changed(M) ->
try
module_vsn(M:module_info()) =/= module_vsn(code:get_object_code(M))
catch _:_ ->
false
end.
%% Internal API
module_vsn({M, Beam, _Fn}) ->
{ok, {M, Vsn}} = beam_lib:version(Beam),
Vsn;
module_vsn(L) when is_list(L) ->
{_, Attrs} = lists:keyfind(attributes, 1, L),
{_, Vsn} = lists:keyfind(vsn, 1, Attrs),
Vsn.
doit(From, To) ->
[case file:read_file_info(Filename) of
{ok, #file_info{mtime = Mtime}} when Mtime >= From, Mtime < To ->
reload(Module);
{ok, _} ->
unmodified;
{error, enoent} ->
%% The Erlang compiler deletes existing .beam files if
%% recompiling fails. Maybe it's worth spitting out a
%% warning here, but I'd want to limit it to just once.
gone;
{error, Reason} ->
error_logger:error_msg("Error reading ~s's file info: ~p~n",
[Filename, Reason]),
error
end || {Module, Filename} <- code:all_loaded(), is_list(Filename)].
reload(Module) ->
error_logger:info_msg("Reloading ~p ...", [Module]),
code:purge(Module),
case code:load_file(Module) of
{module, Module} ->
error_logger:info_msg("reload ~w ok.~n", [Module]),
reload;
{error, Reason} ->
error_logger:error_msg("reload fail: ~p.~n", [Reason]),
error
end.
stamp() ->
erlang:localtime().

+ 2
- 16
src/measure/utProf.erl View File

@ -1,22 +1,6 @@
-module(utProf).
%trace Mod
trace(Mod) ->
dbg:tracer(),
dbg:tpl(Mod, '_', []),
dbg:p(all, c).
%trace Node上指定 Mod , shell
trace(Node, Mod) ->
dbg:tracer(),
dbg:n(Node),
dbg:tpl(Mod, '_', []),
dbg:p(all, c).
%trace
trace_stop() ->
dbg:stop_clear().
% eprof, eprof 线,!
% TimeoutSec<10s< 1000crash
@ -65,3 +49,5 @@ trace(Node, Mod) ->
trace_stop() ->
dbg:stop_clear().
%% ====================================================================

Loading…
Cancel
Save